Nối các cặp phần tử của danh sách


82

Tôi biết rằng một danh sách có thể được kết hợp để tạo thành một chuỗi dài như trong:

x = ['a', 'b', 'c', 'd']
print ''.join(x)

Rõ ràng điều này sẽ xuất ra:

'abcd'

Tuy nhiên, những gì tôi đang cố gắng làm chỉ đơn giản là nối chuỗi đầu tiên và chuỗi thứ hai trong danh sách, sau đó nối chuỗi thứ ba và thứ tư, v.v. Tóm lại, từ ví dụ trên, thay vào đó, hãy đạt được kết quả đầu ra là:

['ab', 'cd']

Có cách nào đơn giản để làm điều này? Tôi có lẽ cũng nên đề cập rằng độ dài của các chuỗi trong danh sách sẽ không thể đoán trước được, cũng như số lượng chuỗi trong danh sách, mặc dù số lượng chuỗi sẽ luôn là số chẵn. Vì vậy, danh sách ban đầu cũng có thể là:

['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'] 

“Tôi có lẽ cũng nên đề cập rằng độ dài của các chuỗi trong danh sách sẽ không thể đoán trước được” - Vậy độ dài có quan trọng không? Tức là bạn chỉ muốn nối mọi cặp phần tử trong danh sách hay bạn thực sự muốn xem nội dung và kết hợp với điều kiện là phần tử kết quả nằm dưới một số giới hạn độ dài đặc biệt?
poke

chỉ đơn giản là tham gia mọi cặp, tôi chỉ nghĩ rằng không biết số lượng các cặp có thể là một vấn đề
John

Câu trả lời:


75

Bạn có thể sử dụng ký hiệu lát cắt với các bước:

>>> x = "abcdefghijklm"
>>> x[0::2] #0. 2. 4...
'acegikm'
>>> x[1::2] #1. 3. 5 ..
'bdfhjl'
>>> [i+j for i,j in zip(x[::2], x[1::2])] # zip makes (0,1),(2,3) ...
['ab', 'cd', 'ef', 'gh', 'ij', 'kl']

Logic tương tự cũng áp dụng cho các danh sách. Chiều dài chuỗi không quan trọng, vì bạn chỉ cần thêm hai chuỗi lại với nhau.


1
Không có nghi ngờ rằng câu trả lời của kevpie tốt hơn nhiều. Trong cái này, x[:::2]tạo một đối tượng, x[1::2]tạo một đối tượng khác, những sáng tạo này có thể dựa trên việc tính toán các chỉ mục bên dưới và lệnh gọi hàm với hai đối tượng này được truyền dưới dạng đối số là cần thiết trước khi có thể lấy các cặp phần tử kế tiếp mà phải được nối. Trong khi trong câu trả lời của kevpie, chỉ có việc tạo một trình lặp và sau đó lặp đi lặp lại từ phần tử này sang phần tử khác của danh sách chưa được chạm mà không cần phải quan tâm đến các chỉ mục và điều đó còn khó hiểu hơn nhiều.
chứng kiến

@eyquem, sử dụng itertools.islicethay vì [], loại bỏ các đối tượng trung gian. Nhưng vì cả hai câu trả lời đều hoạt động trên các điều kiện giống nhau và trả về như nhau nên cả hai đều đúng. Và zip(i[::2], i[1::2])trông rất ngọt ngào với tôi, vậy, tại sao không? :)
utdemir

Điều này chỉ hoạt động trên các chuỗi , trong khi câu trả lời của @ kevpie tổng quát hơn và hoạt động trên bất kỳ chuỗi nào có thể lặp lại .
Kos

37

Sử dụng một trình lặp.

Danh sách hiểu:

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'])
>>> [c+next(si, '') for c in si]
['abcde', 'fghijklmn', 'opqr']
  • Rất hiệu quả để sử dụng bộ nhớ.
  • Chính xác một lần truyền của s

Biểu thức trình tạo:

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'])
>>> pair_iter = (c+next(si, '') for c in si)
>>> pair_iter # can be used in a for loop
<generator object at 0x4ccaa8>
>>> list(pair_iter) 
['abcde', 'fghijklmn', 'opqr']
  • sử dụng như một trình lặp

Sử dụng bản đồ, str .__ add__, iter

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'])
>>> map(str.__add__, si, si)
['abcde', 'fghijklmn', 'opqr']

tiếp theo (trình lặp [, mặc định]) có sẵn bắt đầu bằng Python 2.6


2
Cho đến nay, câu trả lời tốt nhất. Xem bình luận của tôi để trả lời câu trả lời của utdemir.
chứng kiến

4

chỉ để được pythonic :-)

>>> x = ['a1sd','23df','aaa','ccc','rrrr', 'ssss', 'e', '']
>>> [x[i] + x[i+1] for i in range(0,len(x),2)]
['a1sd23df', 'aaaccc', 'rrrrssss', 'e']

trong trường hợp bạn muốn được cảnh báo nếu độ dài danh sách là lẻ, bạn có thể thử:

[x[i] + x[i+1] if not len(x) %2 else 'odd index' for i in range(0,len(x),2)]

May mắn nhất


2

Nếu không tạo danh sách tạm thời:

>>> import itertools
>>> s = 'abcdefgh'
>>> si = iter(s)
>>> [''.join(each) for each in itertools.izip(si, si)]
['ab', 'cd', 'ef', 'gh']

hoặc là:

>>> import itertools
>>> s = 'abcdefgh'
>>> si = iter(s)
>>> map(''.join, itertools.izip(si, si))
['ab', 'cd', 'ef', 'gh']

Tốt, nhưng việc xem xét mã của tôi khiến tôi bắt đầu với danh sách ban đầu, tôi nghĩ không nên chọn cho utdmr's .... cảm ơn bạn
John

1
>>> lst =  ['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'] 
>>> print [lst[2*i]+lst[2*i+1] for i in range(len(lst)/2)]
['abcde', 'fghijklmn', 'opqr']

1

Tôi sẽ làm theo cách này vì tôi không tốt với Regs ..

t = '1. eat, food\n\
7am\n\
2. brush, teeth\n\
8am\n\
3. crack, eggs\n\
1pm'.splitlines()

print [i+j for i,j in zip(t[::2],t[1::2])]

đầu ra:

['1. eat, food   7am', '2. brush, teeth   8am', '3. crack, eggs   1pm']  

Hi vọng điêu nay co ich :)

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.