Lets say I have a dictionary and list like the below:
l: list = [1,2,3,4]
d: dict = {"Hello": "World"}
I want to copy this dictionary exactly len(l)
times.
I want to eventually create a list of tuples that looks like:
[(1, {"Hello": "World"}),(2, {"Hello": "World"}),(3, {"Hello": "World"}),(4, {"Hello": "World"})]
To create this I imagine I could do:
output: list = list(zip(l, repeated_dicts))
but need to replicate the dictionary the specified number of times in the list.
I tried using itertools.islice
and itertools.cycle
but couldn't quite get it. Any ideas?
CodePudding user response:
If you need to perform an actual copy, you cannot simply use the same d
N times, otherwise all elements of your list would refer to the same object (and modifying any of them would modify all the elements).
In your example, .copy()
with a generator expression should suffice:
l = [1,2,3,4]
d = {"Hello": "World"}
output = list((x, d.copy()) for x in l)
You will need copy.deepcopy
if the dictionary also contains other complex objects like sets/lists/classes/dictionaries:
from copy import deepcopy
output = list((x, deepcopy(d)) for x in l)
CodePudding user response:
You're looking for itertools.repeat()
:
Make an iterator that returns object over and over again. Runs indefinitely unless the times argument is specified.
Note that the dictionaries returned by itertools.repeat()
will share the same memory; changes to one dictionary will be shared across all of the elements of the list. That can lead to some pretty confusing behavior.
To avoid this, you can use map()
with copy.copy()
(if everything in the dictionary is immutable) or copy.deepcopy()
to ensure that the memory for each dictionary is separate:
from itertools import repeat
from copy import copy
lst = [1, 2, 3, 4]
d = {"Hello": "World"}
list(zip(lst, map(copy, repeat(d))))
This outputs:
[
(1, {'Hello': 'World'}), (2, {'Hello': 'World'}),
(3, {'Hello': 'World'}), (4, {'Hello': 'World'})
]
CodePudding user response:
Given that these dictionaries are never modified, copy/deepcopy is not necessary. The simplest way to do this (also, least overhead) is:
output = [(i, d) for i in l]
CodePudding user response:
l: list = [1,2,3,4]
d: dict = {"Hello": "World"}
res = []
for num in l:
res.append((num, d.copy()))
>>>(res)
[(1, {'hello': 'World'}), (2, {'hello': 'World'}), (3, {'hello': 'World'})]
CodePudding user response:
It seems you're only copying the dictionary once in your example. Perhaps you can use a list comprehension with tuples?
l = [1, 1, 1]
d = {"Hello": "World"}
output = [(i, d.copy()) for i in range(1, len(l) 1)]
>>> output
[(1, {'Hello': 'World'}), (2, {'Hello': 'World'}), (3, {'Hello': 'World'})]
Or for each number in the list:
>>> l = [1, 1, 1]
>>> [(i, d.copy()) for i in l]
[(1, {'Hello': 'World'}), (1, {'Hello': 'World'}), (1, {'Hello': 'World'})]
Or copying the list i
times:
>>> l = [1, 2, 1]
>>> [(i, [d.copy() for j in range(i)]) for i in l]
[(1, [{'Hello': 'World'}]),
(2, [{'Hello': 'World'}, {'Hello': 'World'}]),
(1, [{'Hello': 'World'}])]