I have a function
that takes a list
of json
strings and replaces [link]
with one item of a list
of links, and I want to replace [link]
with every N
(variable) item of the list
.
import itertools
ll = [
{
'Messages': [
{'id': 'int', 'Text': 'string with [link] !'},
{'id': 'int', 'Text': 'string with [link] !'},
]
},
{
'Messages': [
{'id': 'int', 'Text': 'string with [link] !'},
{'id': 'int', 'Text': 'string with [link] !'},
]
},
{
'Messages': [
{'id': 'int', 'Text': 'string with [link] !'},
{'id': 'int', 'Text': 'string with [link] !'},
]
},
]
links = ['aaa', 'bbb', 'ccc']
def changer(ll):
cy = itertools.cycle(links)
for i in ll:
ni = i.replace('[link]', next(cy))
print(next(cy))
print(type(ni))
For example, if N = 2
for every 2 items of the list
cycle to the next
link.
But my code replaces all with the first element of the list
'aaa' in this case.
The result should look like this:
N = 2
[
{
'Messages': [
{'id': 'int', 'Text': 'string with aaa !'},
{'id': 'int', 'Text': 'string with aaa !'},
]
},
{
'Messages': [
{'id': 'int', 'Text': 'string with aaa !'},
{'id': 'int', 'Text': 'string with aaa !'},
]
},
{
'Messages': [
{'id': 'int', 'Text': 'string with bbb !'},
{'id': 'int', 'Text': 'string with bbb !'},
]
},
{
'Messages': [
{'id': 'int', 'Text': 'string with bbb !'},
{'id': 'int', 'Text': 'string with bbb !'},
]
},
]
CodePudding user response:
Use a simple loop with zip
:
for d1, l in zip(ll, links):
for d2 in d1['Messages']:
d2['Text'] = d2['Text'].replace('[link]', l)
modified ll
:
[{'Messages': [{'id': 'int', 'Text': 'string with aaa !'},
{'id': 'int', 'Text': 'string with aaa !'}]},
{'Messages': [{'id': 'int', 'Text': 'string with bbb !'},
{'id': 'int', 'Text': 'string with bbb !'}]},
{'Messages': [{'id': 'int', 'Text': 'string with ccc !'},
{'id': 'int', 'Text': 'string with ccc !'}]},
]
CodePudding user response:
You could use enumerate()
to assign number
to every item on list and run next(cy)
only when number % N == 0
Working example.
I used more readable names for variables.
import itertools
data = [
{
'Messages': [
{'id': 'int', 'Text': 'string with [link] !'},
{'id': 'int', 'Text': 'string with [link] !'},
]
},
{
'Messages': [
{'id': 'int', 'Text': 'string with [link] !'},
{'id': 'int', 'Text': 'string with [link] !'},
]
},
{
'Messages': [
{'id': 'int', 'Text': 'string with [link] !'},
{'id': 'int', 'Text': 'string with [link] !'},
]
},
]
links = ['aaa', 'bbb', 'ccc']
N = 2
links_cycle = itertools.cycle(links)
for number, item in enumerate(data):
if number % N == 0:
new_link = next(links_cycle)
for message in item['Messages']:
message['Text'] = message['Text'].replace('[link]', new_link)
print(item)
Result:
{'Messages': [{'id': 'int', 'Text': 'string with aaa !'},
{'id': 'int', 'Text': 'string with aaa !'}]}
{'Messages': [{'id': 'int', 'Text': 'string with aaa !'},
{'id': 'int', 'Text': 'string with aaa !'}]}
{'Messages': [{'id': 'int', 'Text': 'string with bbb !'},
{'id': 'int', 'Text': 'string with bbb !'}]}
BTW:
Other method: create list with repeated values
links = ['aaa', 'aaa', 'bbb', 'bbb', 'ccc', 'ccc']
which you can create using
links = [item for item in links for _ in range(N)]
and next run next()
in every loop.
It can be useful when you would repeat some values different times
ie. aaa
x 1 , bbb
x 3 , ccc
x 2
links = ['aaa', 'bbb', 'bbb', 'bbb', 'ccc', 'ccc']
which you caan create using
N = [1, 3, 2]
links = ['aaa', 'bbb', 'ccc']
links = [item for item, number in zip(links, N) for _ in range(number)]