Làm cách nào để sắp xếp lại danh sách? [đóng cửa]


108

Nếu tôi có một danh sách, [a,b,c,d,e]làm thế nào tôi có thể sắp xếp lại các mục theo cách tùy ý [d,c,a,b,e]?

Chỉnh sửa: Tôi không muốn xáo trộn chúng. Tôi muốn sắp xếp lại chúng theo cách đã xác định trước. (ví dụ: tôi biết rằng phần tử thứ 3 trong danh sách cũ sẽ trở thành phần tử đầu tiên trong danh sách mới)


Có thể là bản sao của stackoverflow.com/questions/976882/…
kgiannakakis

4
Nếu không chỉ định cách bạn muốn đặt hàng thì thật khó để trả lời. Bạn có muốn sắp xếp chúng không? Trộn chúng? Xóa một số trong số chúng?
Mizipzor

@tvanfosson: Trong trường hợp này, tùy ý cũng có thể có nghĩa là: lấy một hàm sắp xếp tùy ý (nhưng được xác định rõ).
Felix Kling

1
@mizipzor Tôi muốn sắp xếp lại chúng theo cách xác định trước. (Đã chỉnh sửa câu hỏi để làm rõ điều này)
Niyaz

@SilentGhost Nó sẽ có một chỉ mục mới. Có thể là 4. Vấn đề là tôi biết thứ tự mới của các mặt hàng.
Niyaz

Câu trả lời:


226

Bạn có thể làm điều đó như thế này

mylist = ['a', 'b', 'c', 'd', 'e']
myorder = [3, 2, 0, 1, 4]
mylist = [mylist[i] for i in myorder]
print(mylist)         # prints: ['d', 'c', 'a', 'b', 'e']

1
Điều này tạo ra một biến mới. Làm thế nào để sắp xếp lại một danh sách tại chỗ? Cảm ơn
Bối rối

@Con Founder Đơn giản chỉ cần thay đổi dòng cuối cùng thành:mylist[:] = [mylist[i] for i in myorder]
Adam


11
>>> import random
>>> x = [1,2,3,4,5]
>>> random.shuffle(x)
>>> x
[5, 2, 4, 3, 1]

@ wenlibin02, vừa chạy nó dưới 2.7.5 và nó vẫn hoạt động tốt. Bạn có nhận được một số loại lỗi?
Đánh dấu

không có lỗi, tôi chỉ cần gõ: 1) nhập ngẫu nhiên; x = [1, 2, 3]; ngẫu nhiên.shuffle (x); #it ​​trả về Không có; và 2) Tôi đã thử np.random.shuffle. kết quả là như nhau.
Libin Wen

Ồ xin lỗi! Tôi không nhận ra rằng tôi trực tiếp thay đổi giá trị của x. Nó đã trả về Không có. Và nó hoạt động. Cảm ơn.
Libin Wen,


3
>>> a=["a","b","c","d","e"]
>>> a[0],a[3] = a[3],a[0]
>>> a
['d', 'b', 'c', 'a', 'e']

2

Bạn có thể cung cấp chức năng sắp xếp của riêng mình để list.sort():

Phương thức sort () nhận các đối số tùy chọn để kiểm soát các so sánh.

  • CMP xác định một hàm so sánh tùy chỉnh của hai đối số (mục danh sách) mà phải trả lại một tiêu cực, không hay số dương tùy thuộc vào việc đối số đầu tiên được coi là nhỏ hơn, bằng hoặc lớn hơn số thứ hai: cmp=lambda x,y: cmp(x.lower(), y.lower()). Giá trị mặc định là None.

  • chính quy định cụ thể một chức năng của một đối số được sử dụng để trích xuất một phím so sánh từ mỗi phần tử danh sách: key=str.lower. Giá trị mặc định là None.

  • đảo ngược là một giá trị boolean. Nếu được đặt thành True, thì các phần tử danh sách được sắp xếp như thể mỗi so sánh đã được đảo ngược.

Nói chung, quá trình chuyển đổi khóa và đảo ngược nhanh hơn nhiều so với việc chỉ định một hàm cmp tương đương. Điều này là do cmp được gọi nhiều lần cho mỗi phần tử danh sách trong khi phím và chạm ngược lại mỗi phần tử chỉ một lần.


2
và bạn thực hiện điều này chính xác như thế nào?
SilentGhost

@SilentGhost: Đây là câu trả lời chung chung. Trong trường hợp OPs, câu trả lời của bạn phù hợp hơn. Tuy nhiên, tôi nghĩ điều quan trọng là phải biết rằng một giải pháp chung tồn tại.
Felix Kling

2

Nếu bạn sử dụng numpy, có một cách đơn giản để làm điều đó:

items = np.array(["a","b","c","d"])
indices = np.arange(items.shape[0])
np.random.shuffle(indices)
print(indices)
print(items[indices])

Mã này trả về:

[1 3 2 0]
['b' 'd' 'c' 'a']

1
OP đang tìm kiếm một cách sắp xếp lại cụ thể, không phải một sự xáo trộn chung chung.
Teepeemm

2

Nếu bạn không quan tâm nhiều đến hiệu quả, bạn có thể dựa vào lập chỉ mục mảng của numpy để làm cho nó trở nên thanh lịch:

a = ['123', 'abc', 456]
order = [2, 0, 1]
a2 = list( np.array(a, dtype=object)[order] )

1

Theo những gì tôi hiểu về câu hỏi của bạn, có vẻ như bạn muốn áp dụng một hoán vị mà bạn chỉ định trên a list. Điều này được thực hiện bằng cách chỉ định một list(hãy gọi nó p) khác giữ các chỉ số của các phần tử của bản gốc listsẽ xuất hiện trong hoán vị list. Sau đó, bạn sử dụng pđể tạo mới listbằng cách thay thế phần tử ở mỗi vị trí bằng phần tử có chỉ mục ở vị trí đó p.

def apply_permutation(lst, p):
    return [lst[x] for x in p]

arr=list("abcde")
new_order=[3,2,0,1,4]

print apply_permutation(arr,new_order)

Bản in này ['d', 'c', 'a', 'b', 'e'].

Điều này thực sự tạo ra một mới list, nhưng nó có thể được sửa đổi nhỏ để hoán vị "tại chỗ" ban đầu.


1

Một điều nữa có thể được coi là cách giải thích khác được chỉ ra bởi darkless

Mã bằng Python 2.7

Chủ yếu:

  1. Sắp xếp lại theo giá trị - Đã được AJ giải quyết ở trên
  2. Sắp xếp lại theo chỉ mục

    mylist = ['a', 'b', 'c', 'd', 'e']
    myorder = [3, 2, 0, 1, 4]
    
    mylist = sorted(zip(mylist, myorder), key=lambda x: x[1])
    print [item[0] for item in mylist]

Điều này sẽ in ['c', 'd', 'b', 'a', 'e']



-1

Đây là những gì tôi đã sử dụng khi tôi tình cờ gặp vấn đề này.

def order(list_item, i): # reorder at index i
    order_at = list_item.index(i)
    ordered_list = list_item[order_at:] + list_item[:order_at]
    return ordered_list

EX: cho các chữ cái thường

order(string.ascii_lowercase, 'h'):
>>> 'hijklmnopqrstuvwxyzabcdefg'

Nó chỉ đơn giản là chuyển danh sách sang một chỉ mục cụ thể

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.