2016-04-10 13 views
7

Tôi có danh sách một số thành phần, ví dụ: [1, 2, 3, 4] và một đối tượng, ví dụ: 'a'. Tôi muốn tạo một danh sách các bộ dữ liệu với các phần tử của danh sách ở vị trí đầu tiên và đối tượng đơn ở vị trí thứ hai: [(1, 'a'), (2, 'a'), (3, 'a'), (4, 'a')].Python: danh sách zip có một thành phần đơn lẻ

tôi có thể làm điều đó với zip như thế này:

def zip_with_scalar(l, o): # l - the list; o - the object 
    return list(zip(l, [o] * len(l))) 

Tuy nhiên điều này mang lại cho tôi một cảm giác của việc tạo ra và danh sách không cần thiết lặp lại phần tử.

Một khả năng khác là

def zip_with_scalar(l, o): 
    return [(i, o) for i in l] 

đó là rất sạch sẽ và pythonic thực sự, nhưng ở đây tôi làm toàn bộ điều "thủ công". Trong Haskell tôi sẽ làm một cái gì đó giống như

zipWithScalar l o = zip l $ repeat o 

Có tích hợp chức năng hoặc lừa, hoặc là cho nén với vô hướng hoặc kiếm cái gì đó sẽ cho phép tôi sử dụng zip bình thường, ví dụ sắp xếp của danh sách vô hạn?

+3

https://docs.python.org/3/library/itertools.html#itertools.repeat – jonrsharpe

+0

gì jonrsharpe nói, nhưng cũng có thể bạn muốn viết lại đó như một máy phát điện, chứ không phải là một chức năng thông thường. – OmnipotentEntity

+3

@OmnipotentEntity như OP đang sử dụng 3.x họ chỉ có thể 'return zip (l, repeat (o))'; đó là một iterator, không cần phải 'yield'. – jonrsharpe

Trả lời

11

Đây là cloest đến giải pháp Haskell của bạn:

import itertools 

def zip_with_scalar(l, o): 
    return zip(l, itertools.repeat(o)) 

Bạn cũng có thể sử dụng máy phát điện, mà tránh tạo ra một danh sách như comprehensions làm:

def zip_with_scalar(l, o): 
    return ((i, o) for i in l) 
2

Bạn cũng có thể sử dụng zip_longest với một fillvalue của o:

from itertools import zip_longest 

def zip_with_scalar(l, o): # l - the list; o - the object 
    return zip_longest(l, [o], fillvalue=o) 

print(list(zip_with_scalar([1, 2, 3, 4] ,"a"))) 

Chỉ cần lưu ý rằng mọi giá trị có thể thay đổi được sử dụng cho o sẽ không được sao chép dù sử dụng zip_longest hoặc lặp lại.

3

Bạn có thể sử dụng được xây dựng trong map chức năng:

>>> elements = [1, 2, 3, 4] 
>>> key = 'a' 
>>> map(lambda e: (e, key), elements) 
[(1, 'a'), (2, 'a'), (3, 'a'), (4, 'a')] 
0

Bạn có thể làm rất nhiều với chỉ *

elements = [1, 2, 3, 4] 
single_object = 'a' 

zip(elements, single_object * len(elements)) 
+0

. một số ví dụ. Và OP đã làm một cái gì đó tương tự – Copperfield

+0

Đây không phải là giải pháp đầu tiên mà OP đã đưa ra? – refi64

1

Đây là một công việc hoàn hảo cho lớp itertools.cycle.

from itertools import cycle 


def zip_with_scalar(l, o): 
    return zip(i, cycle(o)) 

Demo:

>>> from itertools import cycle 
>>> l = [1, 2, 3, 4] 
>>> list(zip(l, cycle('a'))) 
[(1, 'a'), (2, 'a'), (3, 'a'), (4, 'a')] 
+0

Đối số cho '' cycle'' phải là một iterable, phải không? Nó hoạt động với '' 'a''' vì nó là chuỗi, nhưng không phải với một đối tượng tùy ý. – zegkljan

+0

@zegkljan yes nó phải là một iterable. – styvane

0
lst = [1,2,3,4] 
tups = [(itm, 'a') for itm in lst] 
tups 

> [(1, 'a'), (2, 'a'), (3, 'a'), (4, 'a')] 
Các vấn đề liên quan