2016-04-10 6 views
7

У меня есть список некоторых элементов, например. [1, 2, 3, 4] и один объект, например. 'a'. Я хочу создать список кортежей с элементами списка в первой позиции и единственным объектом во второй позиции: [(1, 'a'), (2, 'a'), (3, 'a'), (4, 'a')].Python: zip-список с одним элементом

я мог бы сделать это с zip как это:

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

Однако это дает мне чувство создания и ненужному список повторяющимся элементы.

Другая возможность

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

который очень чистый и вещий, конечно, но здесь я делаю все это «вручную». В Haskell я хотел бы сделать что-то вроде

zipWithScalar l o = zip l $ repeat o 

Есть ли встроенные функции или трюк, либо для архивирования с скаляр или что-то, что позволило бы мне использовать обычный почтовый индекс, т.е. сортировки бесконечного списка?

+3

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

+0

Что jonrsharpe сказал, но и вы, вероятно, хотите переписывайте это как генератор, а не как регулярную функцию. – OmnipotentEntity

+3

@OmnipotentEntity, поскольку OP использует 3.x, они могут просто «возвращать zip (l, repeat (o))'; это итератор, не нужно «уступать». – jonrsharpe

ответ

11

Это cloest к вашему решению Haskell:

import itertools 

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

Вы можете также использовать генераторы, которые позволяют избежать создания списка, как постижения сделать:

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

Вы также можете использовать zip_longest с заполнение 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"))) 

Просто имейте в виду, что любые измененные значения, используемые для o, не будут скопированы с использованием zip_longest или repeat.

3

Вы можете использовать встроенный в map функции:

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

Вы можете сделать много только с *

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

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

, это работает только в том случае, если единственным объектом является последовательность только из 1 элемента, она, несомненно, приведет к нежелательным результатам с чем-либо еще, например например, число. И OP уже делают что-то подобное. – Copperfield

+0

Разве это не первое решение, которое дал OP? – refi64

1

Это идеальная работа для itertools.cycle класса.

from itertools import cycle 


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

Демо:

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

Аргумент '' цикл'' должен быть итерируемым, не так ли? Он работает с '' 'a''', поскольку это строка, но не с произвольным объектом. – zegkljan

+0

@zegkljan да, он должен быть итерируемым. – styvane

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

> [(1, 'a'), (2, 'a'), (3, 'a'), (4, 'a')] 
Смежные вопросы