2012-01-18 50 views
9

Tôi đã nhận được một cái gì đó với Python mà tôi không thể hiểu được. Tôi có một danh sách liệt kê, được gọi là dữ liệu:Sao chép danh sách không hoạt động?

data = [[75], [95, 64], [17, 47, 82], [18, 35, 87, 10], [20, 4, 82, 47, 65], [19, 1, 23, 75, 3, 34], [88, 2, 77, 73, 7, 63, 67], [99, 65, 4, 28, 6, 16, 70, 92], [41, 41, 26, 56, 83, 40, 80, 70, 33], [41, 48, 72, 33, 47, 32, 37, 16, 94, 29], [53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14], [70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57], [91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48], [63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31], [4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23]] 

Tôi muốn tạo ra một bản sao của dữ liệu, mà dữ liệu sẽ được đảo ngược (1 trở thành 99 và vân vân).

Sau đó tôi có sorted_values ​​và những người ngược lại:

sorted_vals = [1, 2, 3, 4, 6, 7, 9, 10, 11, 14, 16, 17, 18, 19, 20, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 43, 44, 47, 48, 50, 51, 52, 53, 56, 57, 58, 60, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 75, 77, 78, 80, 82, 83, 87, 88, 89, 91, 92, 93, 94, 95, 97, 98, 99] 
reverse_vals = [99, 98, 97, 95, 94, 93, 92, 91, 89, 88, 87, 83, 82, 80, 78, 77, 75, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 60, 58, 57, 56, 53, 52, 51, 50, 48, 47, 44, 43, 41, 40, 39, 38, 37, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 23, 20, 19, 18, 17, 16, 14, 11, 10, 9, 7, 6, 4, 3, 2, 1] 

tôi có thể tạo một bản sao của dữ liệu:

rev_data = data[:] 

Sau đó, tôi thay đổi dữ liệu trong khi chạy qua danh sách của tôi:

for index, item in enumerate(rev_data): 
    for s_index, s_item in enumerate(item): 
     rev_data[index][s_index] = reverse_val[sort_val.index(s_item)] 

Vấn đề của tôi là bất kỳ phương pháp nào của tôi để tạo vòng quay, dữ liệu cũng được sửa đổi trong quá trình này!

tôi đã cố gắng:

rev_data = list(data) 
rev_data = data[:] 

rev_data = [] 
rev_data.extend(data) 

Mỗi lần, câu trả lời cuối cùng là chính xác, nhưng dữ liệu cũng được thay đổi. . .

data = [[25], [4, 35], [83, 52, 18], [82, 64, 16, 91], [78, 95, 18, 52, 34], [80, 99, 77, 25, 97, 65], [14, 98, 23, 26, 93, 37, 32], [1, 34, 95, 71, 94, 87, 29, 9], [57, 57, 73, 43, 17, 58, 19, 29, 66], [57, 51, 27, 66, 52, 67, 63, 87, 6, 70], [44, 28, 53, 34, 75, 56, 10, 47, 3, 48, 88], [29, 89, 66, 71, 23, 26, 83, 20, 60, 31, 83, 41], [10, 28, 47, 62, 83, 88, 10, 56, 40, 50, 72, 70, 51], [37, 33, 95, 31, 11, 44, 32, 69, 26, 87, 30, 16, 58, 68], [95, 38, 2, 72, 77, 92, 29, 2, 26, 7, 62, 44, 39, 95, 77]] 
+0

có một số câu hỏi yêu cầu tương tự, như thế này: http://stackoverflow.com/questions/6993531/ copy-list-in-python và cái này: http://stackoverflow.com/questions/8350750/python-copy-list-issue – juliomalegria

Trả lời

19

data[:] tạo ra một nông bản sao của danh sách data. Do đây là một danh sách liệt kê, và bạn cũng muốn sao chép danh sách bên trong, bạn cần một sâu bản sao thay vì:

rev_data = copy.deepcopy(data) 

hoặc

rev_data = [x[:] for x in data] 
+0

Con người, rất nhiều câu trả lời trong 15 giây! o_O. Tôi biết nó phải là một cái gì đó với danh sách lồng nhau; whithout thực sự nhận được điều. Cảm ơn tất cả các bạn! – jlengrand

+2

Điều đáng chú ý là 'deepcopy' đi kèm với một hit hiệu suất khá lớn (thường là một thứ tự độ lớn) so với một danh sách hiểu như thế này. Vì vậy, nếu bạn có thể chắc chắn rằng danh sách của bạn sẽ luôn được cấu trúc theo cùng một cách, bạn có thể sẽ tốt hơn với tùy chọn thứ hai. – Wilduck

6

Bạn có danh sách danh sách lồng nhau, vì vậy bạn cần sao chép hai cấp sâu.

data_copy = [inner_list[:] for inner_list in data] 
7

sử dụng copy.deepcopy để sao chép các đối tượng có thể thay đổi lồng nhau.

import copy 
rev_data = copy.deepcopy(data) 
.....................  

Đó là:

>>> import copy 
>>> data = [[75], [95, 64], [17, 47, 82], [18, 35, 87, 10], [20, 4, 82, 47, 65], [19, 1, 23, 75, 3, 34], [88, 2, 77, 73, 7, 63, 67], [99, 65, 4, 28, 6, 16, 70, 92], [41, 41, 26, 56, 83, 40, 80, 70, 33], [41, 48, 72, 33, 47, 32, 37, 16, 94, 29], [53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14], [70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57], [91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48], [63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31], [4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23]] 
>>> reverse_vals = [99, 98, 97, 95, 94, 93, 92, 91, 89, 88, 87, 83, 82, 80, 78, 77, 75, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 60, 58, 57, 56, 53, 52, 51, 50, 48, 47, 44, 43, 41, 40, 39, 38, 37, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 23, 20, 19, 18, 17, 16, 14, 11, 10, 9, 7, 6, 4, 3, 2, 1] 
>>> sorted_vals = [1, 2, 3, 4, 6, 7, 9, 10, 11, 14, 16, 17, 18, 19, 20, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 43, 44, 47, 48, 50, 51, 52, 53, 56, 57, 58, 60, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 75, 77, 78, 80, 82, 83, 87, 88, 89, 91, 92, 93, 94, 95, 97, 98, 99] 
>>> for index, item in enumerate(rev_data): 
...  for s_index, s_item in enumerate(item): 
...   rev_data[index][s_index] = reverse_vals[sorted_vals.index(s_item)] 
...   
>>> data 
[[75], [95, 64], [17, 47, 82], [18, 35, 87, 10], [20, 4, 82, 47, 65], [19, 1, 23, 75, 3, 34], [88, 2, 77, 73, 7, 63, 67], [99, 65, 4, 28, 6, 16, 70, 92], [41, 41, 26, 56, 83, 40, 80, 70, 33], [41, 48, 72, 33, 47, 32, 37, 16, 94, 29], [53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14], [70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57], [91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48], [63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31], [4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23]] 
>>> rev_data 
[[25], [4, 35], [83, 52, 18], [82, 64, 16, 91], [78, 95, 18, 52, 34], [80, 99, 77, 25, 97, 65], [14, 98, 23, 26, 93, 37, 32], [1, 34, 95, 71, 94, 87, 29, 9], [57, 57, 73, 43, 17, 58, 19, 29, 66], [57, 51, 27, 66, 52, 67, 63, 87, 6, 70], [44, 28, 53, 34, 75, 56, 10, 47, 3, 48, 88], [29, 89, 66, 71, 23, 26, 83, 20, 60, 31, 83, 41], [10, 28, 47, 62, 83, 88, 10, 56, 40, 50, 72, 70, 51], [37, 33, 95, 31, 11, 44, 32, 69, 26, 87, 30, 16, 58, 68], [95, 38, 2, 72, 77, 92, 29, 2, 26, 7, 62, 44, 39, 95, 77]] 
0

reverse_data = reversed(data)

reverse_data sẽ một trình lặp. Bạn có thể lướt qua nó hoặc buộc nó vào danh sách với list(reverse_data).

Thông tin thêm về các chức năng được tích hợp sẵn: http://docs.python.org/library/functions.html#reversed - Để dưới gối.

Edit: nếu bạn chỉ muốn có một danh sách các giá trị trừ 100:

from operator import sub 
from functools import partial 
subtract_map = partial(map, partial(sub,100)) # this is more convenient than a nested list comprehension 
complements = [subtract_map(l) for l in data] 
+0

Downvoter: Có chuyện gì vậy? Đừng tin rằng bạn có thể làm điều này một cách dễ dàng? – Marcin

+1

Không thực sự biết lý do: s. Cảm ơn cho mẹo anyway;) – jlengrand

+0

Thú vị. Tôi không biết về 'đảo ngược' – Benjamin

Các vấn đề liên quan