Home > Mobile >  Element wise operations of uneven list in python
Element wise operations of uneven list in python

Time:07-12

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']
  • Related