2011-11-18 41 views
114

Tôi đang cố gắng hiểu xem có nên lấy nội dung của danh sách và thêm nó vào danh sách khác hay không.Python: lấy nội dung của một danh sách và nối nó vào một danh sách khác

Tôi có danh sách đầu tiên tạo ra máng một chức năng vòng lặp, mà sẽ nhận được dòng cụ thể ra khỏi một tập tin và sẽ lưu chúng trong một danh sách.

Sau đó, danh sách thứ hai được sử dụng để lưu các dòng này và bắt đầu một chu kỳ mới trên một tệp khác.

Ý tưởng của tôi là lấy danh sách khi chu trình được thực hiện, đổ nó vào danh sách thứ hai, sau đó bắt đầu chu kỳ mới, kết xuất nội dung của danh sách thứ nhất vào lần thứ hai nhưng thêm nó vào, danh sách sẽ là tổng của tất cả các tệp danh sách nhỏ hơn được tạo trong vòng lặp của tôi. Danh sách này phải được nối thêm chỉ khi các điều kiện nhất định đáp ứng.

Dường như một cái gì đó tương tự như sau:

# This is done for each log in my directory, i have a loop running 
for logs in mydir: 

    for line in mylog: 
     #...if the conditions are met 
     list1.append(line) 

    for item in list1: 
     if "string" in item: #if somewhere in the list1 i have a match for a string 
      list2.append(list1) # append every line in list1 to list2 
      del list1 [:] # delete the content of the list1 
      break 
     else: 
      del list1 [:] # delete the list content and start all over 

Liệu này có ý nghĩa hay tôi nên đi cho một con đường khác?

Tôi cần một cái gì đó hiệu quả sẽ không mất quá nhiều chu kỳ, vì danh sách nhật ký dài và mỗi tệp văn bản là khá lớn; vì vậy tôi nghĩ rằng các danh sách sẽ phù hợp với mục đích.

Trả lời

220

Bạn có thể muốn

list2.extend(list1) 

thay vì

list2.append(list1) 

Đây là sự khác biệt:

>>> a = range(5) 
>>> b = range(3) 
>>> c = range(2) 
>>> b.append(a) 
>>> b 
[0, 1, 2, [0, 1, 2, 3, 4]] 
>>> c.extend(a) 
>>> c 
[0, 1, 0, 1, 2, 3, 4] 

Kể từ list.extend() chấp nhận một iterable tùy ý, bạn cũng có thể thay thế

for line in mylog: 
    list1.append(line) 

bởi

list1.extend(mylog) 
9

Hãy xem itertools.chain kiếm một cách nhanh chóng để điều trị nhiều danh sách nhỏ như một danh sách lớn duy nhất (hoặc ít nhất là một iterable lớn duy nhất) mà không cần sao chép danh sách nhỏ hơn:

>>> import itertools 
>>> p = ['a', 'b', 'c'] 
>>> q = ['d', 'e', 'f'] 
>>> r = ['g', 'h', 'i'] 
>>> for x in itertools.chain(p, q, r): 
     print x.upper() 
+0

That sounds really trơn! Tôi sẽ xem xét nó để xem nếu tôi có thể thay thế mã mà tôi đã có bằng cách sử dụng itertools! – user1006198

3

Điều đó có vẻ khá hợp lý đối với những gì bạn đang cố gắng làm.

Một phiên bản ngắn hơn một chút mà nghiêng về Python để làm nhiều hơn việc nâng hạng nặng có thể là:

for logs in mydir: 

    for line in mylog: 
     #...if the conditions are met 
     list1.append(line) 

    if any(True for line in list1 if "string" in line): 
     list2.extend(list1) 
    del list1 

    .... 

Các (True for line in list1 if "string" in line) lặp trên list và phát ra True bất cứ khi nào một trận đấu được tìm thấy. any() sử dụng đánh giá ngắn mạch để trả lại True ngay khi tìm thấy phần tử True đầu tiên. list2.extend() nối nội dung của list1 vào cuối.

+0

Cảm ơn bạn đã chỉ ra rằng tối ưu hóa Kirk! – user1006198

+1

'bất kỳ (True cho dòng trong list1 nếu" chuỗi "trong dòng)' gọn gàng hơn được viết là 'bất kỳ (" chuỗi "trong dòng cho dòng trong list1)'. –

+0

Điểm tốt, @KarlKnechtel, mặc dù chúng khác nhau một cách tinh tế. Phiên bản của bạn luôn phát ra * thứ gì đó *, Đúng hoặc Sai. Mỏ chỉ phát ra một sự thật. Tôi không biết làm thế nào những điểm chuẩn đó ra, hoặc liệu có đủ sự khác biệt về vật chất hay không. –

2

Sử dụng map()reduce() built-in chức năng

def file_to_list(file): 
    #stuff to parse file to a list 
    return list 

files = [...list of files...] 

L = map(file_to_list, files) 

flat_L = reduce(lambda x,y:x+y, L) 

tối thiểu "cho vòng lặp" và mẫu mã thanh lịch :)

0

Để recap trên câu trả lời trước. Nếu bạn có danh sách với [0,1,2] và một danh sách khác có [3,4,5] và bạn muốn hợp nhất chúng, do đó, nó sẽ trở thành [0,1,2,3,4,5], bạn có thể sử dụng chaining hoặc extending và nên biết sự khác biệt để sử dụng nó một cách khôn ngoan cho nhu cầu của bạn.

Mở rộng danh sách

Sử dụng list lớp extend phương pháp, bạn có thể làm một bản sao của các yếu tố từ một danh sách lên nhau. Tuy nhiên điều này sẽ gây ra việc sử dụng bộ nhớ bổ sung, điều này sẽ tốt trong hầu hết các trường hợp, nhưng có thể gây ra vấn đề nếu bạn muốn có bộ nhớ hiệu quả.

a = [0,1,2] 
b = [3,4,5] 
a.extend(b) 
>>[0,1,2,3,4,5] 

enter image description here

Chaining một danh sách

Trái bạn có thể sử dụng itertools.chain để dây nhiều danh sách, mà sẽ trả về một cái gọi là iterator có thể được sử dụng để lặp qua các danh sách. Đây là bộ nhớ hiệu quả hơn vì nó không phải là sao chép các yếu tố trên nhưng chỉ trỏ đến danh sách tiếp theo.

from itertools import chain 
a = [0,1,2] 
b = [3,4,5] 
c = itertools.chain(a, b) 

enter image description here

Thực hiện một iterator trả về các yếu tố từ iterable đầu tiên cho đến khi nó được sử dụng hết, rồi tiến tới iterable tiếp theo, cho đến khi tất cả các iterables đang cạn kiệt. Được sử dụng để xử lý chuỗi liên tiếp dưới dạng một chuỗi đơn.

0

Nếu chúng ta có danh sách như dưới đây:

list = [2,2,3,4] 

hai cách để sao chép nó vào một danh sách khác.

1.

x = [list] # x =[] x.append(list) same 
print("length is {}".format(len(x))) 
for i in x: 
    print(i) 
length is 1 
[2, 2, 3, 4] 

2.

x = [l for l in list] 
print("length is {}".format(len(x))) 
for i in x: 
    print(i) 
length is 4 
2 
2 
3 
4 
Các vấn đề liên quan