почтовый список с одним элементом
У меня есть список некоторых элементов, например, [1, 2, 3, 4]
и одного объекта, например, 'a'
. Я хочу создать список кортежей с элементами списка в первой позиции и единственным объектом во второй позиции: [(1, 'a'), (2, 'a'), (3, 'a'), (4, 'a')]
.
Я мог бы сделать это с 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]
что действительно очень чисто и питонично, но здесь я делаю все это "вручную". В Хаскеле я бы сделал что-то вроде
zipWithScalar l o = zip l $ repeat o
Существует ли какая-либо встроенная функция или прием, либо для архивирования со скаляром, либо для чего-то, что позволило бы мне использовать обычный zip, то есть бесконечный список?
Ответы
Ответ 1
Это самое лучшее для вашего решения 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
Вы можете использовать встроенную функцию map
:
>>> elements = [1, 2, 3, 4]
>>> key = 'a'
>>> map(lambda e: (e, key), elements)
[(1, 'a'), (2, 'a'), (3, 'a'), (4, 'a')]
Ответ 3
Это идеальная работа для класса 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')]
Ответ 4
lst = [1,2,3,4]
tups = [(itm, 'a') for itm in lst]
tups
> [(1, 'a'), (2, 'a'), (3, 'a'), (4, 'a')]
Ответ 5
Вы также можете использовать zip_longest с fillvalue 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.
Ответ 6
Просто определите класс с бесконечным итератором, который инициализируется единственным элементом, который вы хотите добавить в списки:
class zipIterator:
def __init__(self, val):
self.__val = val
def __iter__(self):
return self
def __next__(self):
return self.__val
а затем создайте свой новый список из этого класса и списки, которые у вас есть:
elements = [1, 2, 3, 4]
key = 'a'
res = [it for it in zip(elements, zipIterator(key))]
результат будет:
>>res
[(1, 'a'), (2, 'a'), (3, 'a'), (4, 'a')]