I am trying to element wise operation on 2 list. But in this case the list are of 2 different sizes. For example we have 2 lists. List 1 contains users and list 2 contains posts. In 1st use case if user list in longer then post, then each user first finish the post of the same index and then the list should start again.
user = [1,2,3,4,5]
posts = ['p1','p2']
posting = ['1 p1','2 p2','3 p1','4 p2','5p1'] so on so forth.
I tried something like this
def send_post(u, t):
print("execute ---------->", u, t)
return "done"
def send_t(ulist, tlist):
print("################## equal processing done")
remaining_accounts = ulist[len(tlist) - len(ulist):]
ulist_counter = len(remaining_accounts)
tlist_counter = len(tlist)
for j in range(len(remaining_accounts)):
if tlist_counter == 0:
send_t(remaining_accounts, tlist)
send_post(remaining_accounts[j], tlist[j])
ulist_counter -= 1
tlist_counter -= 1
if ulist_counter ==0:
break
#
#
#
ulist = ['u1', 'u2', 'u3', "u4", "u5"]
tlist = ['t1', 't2']
send_t(ulist,tlist)
I am new to recursion and python. please help. I am getting this error.
execute ----------> u3 t1
execute ----------> u4 t2
################## equal processing done
execute ----------> u5 t1
Traceback (most recent call last):
File ".\tests.py", line 72, in <module>
send_t(ulist,tlist)
File ".\tests.py", line 59, in send_t
send_post(remaining_accounts[j], tlist[j])
IndexError: list index out of range
CodePudding user response:
itertools.cycle
is helpful here.
from itertools import cycle
users = [1, 2, 3, 4, 5]
posts = ["p1", "p2"]
posting = list(" ".join(x) for x in zip(map(str, users), cycle(posts)))
# ^^^^^^^^
# This conversion was done because int
# instances are not allowed to be joined
# so we have ot convert them to str
print(posting) # ['1 p1', '2 p2', '3 p1', '4 p2', '5 p1']
Let's convert this to a function for modularity.
from itertools import cycle
def cycled_zip(iterable, cycled_itr, join=" "):
return [join.join(itr) for itr in zip(map(str, iterable), cycle(cycled_itr))]
users = [*range(10)] # 0, 1, 2, ..., 9
posts = ["p1", "p2"]
print(cycled_zip(users, posts))
# ['0 p1', '1 p2', '2 p1', '3 p2', '4 p1', '5 p2', '6 p1', '7 p2', '8 p1', '9 p2']
CodePudding user response:
>>> import itertools
>>> users = map(str, range(1, 5))
>>> posting = ["{} {}".format(x, next(y)) for x, y in zip(users, cycle(["p1", "p2"]))]
>>> posting
['1 p1', '2 p2', '3 p1', '4 p2', '5 p1']
CodePudding user response:
itertools
is your friend, it helps you avoid recursion and can really simplify your code!
import itertools
users = [1, 2, 3, 4, 5]
posts = ['p1', 'p2']
# Determine the number of elements we'll actually need.
max_len = max(len(users), len(posts))
# Make iterators that cycle indefinitely after being exhausted.
users_cycle = itertools.cycle(users)
posts_cycle = itertools.cycle(posts)
# Slice the elements we actually need.
pairings = itertools.islice(zip(users_cycle, posts_cycle), max_len)
# Now we can do whatever we'd like with the pairings!
print(', '.join(f'{user} {post}' for user, post in pairings))
# Prints: '1 p1, 2 p2, 3 p1, 4 p2, 5 p1'
CodePudding user response:
another use of itertools:
from itertools import cycle
c = cycle(posts)
posting = [f'{i} {next(c)}' for i in user]
>>> posting
['1 p1', '2 p2', '3 p1', '4 p2', '5 p1']