TypeScriptBody
TypeScriptBody

Reputation: 83

How to unpack this list comprehension

I got some lists of all integer. If use this example filter = [x for x in res if all(item in x for item in v_h) ] it got the result as 3441.

If I unpack it like this:

f = []

for x in res:
    for item in v_h:
        if item in x:
            if all(x):
                f.append(x)

I get 39490, how do I unpack it correctly?

full code:

import time

start_time = time.time()

def make_comb(goal, nums):
    lists = [[num] for num in nums]
    new_lists = []
    collected = []
    while lists:
        for list in lists:
            s = sum(list)
            for num in nums:
                if num >= list[-1]:
                    if s + num < goal:
                        new_lists.append(list + [num])
                    elif s + num == goal:
                        collected.append(list + [num])
        lists = new_lists
        new_lists = []
    return collected



h = 240
v_h = [3,6,9,18,24]

sizes = []
[sizes.append(x) for x in v_h if x not in sizes]

res = make_comb(h, v_h)

filter = [x for x in res if all(item in x for item in v_h) ]

f = []

for x in res:
    for item in v_h:
        if item in x:
            if all(x):
                f.append(x)

# print(*filter, sep="\n")
print("--- %s valid combinations ---" % len(f))
print("--- %s valid combinations ---" % len(filter))
print("--- %s total combinations ---" % len(res))
print("--- %s seconds ---" % (time.time() - start_time))

Upvotes: 2

Views: 100

Answers (3)

Krishna Sai
Krishna Sai

Reputation: 301

If my answer is wrong any criticism is welcome.

filter = []
for x in res:
    execute = True
    for item in v_h:
        if(item not in x):
            execute = False
            break;
    if(execute):
        filter.append(x)

Upvotes: 1

chepner
chepner

Reputation: 531055

You have an unnecessary call to all in your unpacking. You can simulate x with a for loop with an else clause.

filter = []
for x in res:
    for item in v_h:
        if item not in x:
            break
    else:
        filter.append(x)

x will be added to filter if the inner loop completes without ever reaching the break statement, i.e., if item not in x is always false.

Keeping all,

filter = []
for x in res:
    if all(item in x for item in v_h):
        filter.append(x)

which can be seen to mirror the structure of the original list comprehension more closely.

Upvotes: 2

Chrispresso
Chrispresso

Reputation: 4071

filter = [x for x in res if all(item in x for item in v_h) ]

Is this:

ret = []
for x in res:
    append = True
    for item in v_h:
        if item not in x:
            append = False
            break
    if append:
        ret.append(x)
      

Then you can check if it's not in x and set a flag whether or not to append x

Upvotes: 3

Related Questions