Tham gia các phần tử của danh sách nếu các phần tử đó nằm ở giữa hai khoảng trắng


24

Tôi có một đầu vào như thế này:

['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

Tôi muốn tham gia các yếu tố giữa ''để có đầu ra như thế này:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

Tôi đã thử sử dụng joinvà liệt kê cắt như thế này:

a=['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
a[2:5] = [''.join(a[ 2: 5])]
a=['assembly', '', 'python', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

Điều này hoạt động ở một mức độ nào đó nhưng tôi không biết làm thế nào để lặp lại hướng dẫn này cho toàn bộ danh sách.

Câu trả lời:


27

Sử dụng itertools.groupby:

from itertools import groupby

l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
new_l = [''.join(g) for k, g in groupby(l, key = bool) if k]

Đầu ra:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

2
Giải thích: Điều này sử dụng "bool" để kiểm tra giá trị "Falsey", như chuỗi rỗng hoặc Không có.
noɥʇʎԀʎzɐɹƆ

7

Điều này là khủng khiếp và hacky, nhưng

lambda b:lambda l:''.join(i or b for i in l).split(b)

có thể lấy bất kỳ chuỗi nào bạn có thể đảm bảo không có trong phần nối của danh sách và trả về một hàm làm những gì bạn muốn. Tất nhiên, bạn có thể chỉ muốn sử dụng điều này một hoặc hai lần cho tình huống cụ thể của mình, vì vậy, nếu bạn có thể đảm bảo rằng không có phần tử nào trong danh sách chứa một khoảng trắng, nó có thể trông giống như:

a = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
a = ''.join(i or ' ' for i in a).split(' ')

4

Nếu bạn không thể hoặc không muốn sử dụng itertools:

l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
l_new = []
combined = ""
for idx, s in enumerate(l):
    if s != "":
        combined += s
        if idx == len(l)-1:
            l_new.append(combined)

    else:
        l_new.append(combined)
        combined = ""

3

Bạn có thể làm được việc này:

a = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
indx = ['' == k for k in a]
indx = [i for i, x in enumerate(indx) if x] # get the indices.
a_merged = a[0:indx[0]] + [''.join(a[indx[i]:indx[i+1]]) for i in range(len(indx)) if i < len(indx)-1] + a[indx[-1]+1:] # merge the list

Đầu ra:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

Chỉnh sửa sau khi bình luận:

a = ['assembly', '','',  'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
indx = [i for i, x in enumerate(a) if x == ''] # get the indices where '' occurs in the original list. 
a_merged = a[0:indx[0]] + [''.join(a[indx[i]:indx[i+1]]) for i in range(len(indx)) if i < len(indx)-1 and indx[i+1] -indx[i] > 1] + a[indx[-1]+1:]
a_merged

Đầu ra:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

# get the indices.không phải là một bình luận rất hữu ích. Tôi sẽ đề nghị bạn làm cho nó hữu ích (ví dụ filter the indices to keep only those that correspond to whitespace), hoặc loại bỏ nó hoàn toàn.
Alexander - Tái lập Monica

Ngoài ra, không thể đơn giản hóa quá trình 2 bước indices = [i for s in a if s == '']?
Alexander - Tái lập Monica

@Alexander Tôi nghĩ đề xuất của bạn cho dòng 2 sẽ là lỗi cú pháp. Dòng 2 có thể bị xóa nếu bạn chỉ cần thêm kiểm tra "bằng chuỗi null" vào dòng ba nhưindx = [i for i, x in enumerate(a) if x == '']
Reimus Klinsman

Thật không may, câu trả lời này không tính đến yếu tố đầu tiên hoặc cuối cùng là thứ nên được tham gia. thích a = ['asse','mbly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c+', '+']nhưng có vẻ như bạn có thể cải thiện dòng 3 của mình bằng cách nối thêm một danh sách với chuỗi null ở hai đầu enumerate([''] + a + [''])sau đó xóa a[0:indx[0]]a[indx[-1]+1:]trên dòng 4. Điều này vẫn không tính đến nếu có hai chuỗi null ngay bên cạnh nhau mặc dù
Reimus Klinsman

1
Cảm ơn @KeiNagase cho ý kiến ​​tốt. Xem chỉnh sửa.
ngây thơ

2

Nếu các dấu phân cách đầu vào thực sự là các chuỗi rỗng, thì bạn có thể làm

strlist = [x or ' ' for x in a]
joined = ''.join(strlist).split()
joined
['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

Xin lỗi, không thấy câu trả lời của Chuỗi không liên quan. Nếu bạn tách () mà không có tham số, nó sẽ thu gọn tất cả các khoảng trắng, mạnh hơn một chút.
realgeek

1

Khá cũ nhưng vẫn hữu ích:

from itertools import groupby

lst = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

new_lst = [''.join(values)
           for key, values in groupby(lst, key = lambda x: x == '')
           if not key]
print(new_lst)

Sản lượng này

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

1

chạy một vòng lặp trong danh sách
bên trong vòng lặp nối phần tử vào một chuỗi trống tạm thời và kiểm tra điều kiện xem phần tử đó là một chuỗi rỗng hay phần tử cuối cùng của danh sách, nếu đúng thì nối biến tạm thời vào danh sách đầu ra và thay đổi giá trị của biến đó thành một chuỗi rỗng
:

x=['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
temp=''
output=[]
for y in x:
    temp=temp+y
    if y=='' or y==x[-1]:
        output.append(temp)
        temp=''

print(output)

Đầu ra: ['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']


1

Tôi đồng ý rằng câu trả lời Cris sử dụng hầu hết cách tiếp cận python , nhưng sẽ rất tốt để điều chỉnh câu trả lời của Cris một chút. Thay vì sử dụng groupby(l,key = bool)để sử dụng groupby(l, key = lambda x: x !='')và thoát khỏi sự mơ hồ không cần thiết

from itertools import groupby

separator = ''
l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
new_l = [''.join(g) for k, g in groupby(l, key = lambda x: x !=separator) if k]

Như đã nói trong The Zen of Python : Explicit tốt hơn ẩn

Tái bút: Tôi chỉ viết câu trả lời mới vì tôi không đủ uy tín để viết bình luận về câu trả lời Cris .


1

Một phiên bản làm việc khác, chỉ có các vòng / kiểm tra cơ bản:

txt = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

out = []
temp = ''

for s in txt:
   if s == '':
      if temp != '':
         out.append(temp) 
         temp = ''
      out.append('')
   else:
      temp = temp + s

if temp != '':
   out.append(temp)

out
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.