Please improve these comprehensions (was meaning of [ ])
Ben Bacarisse
ben.usenet at bsb.me.uk
Tue Sep 5 09:28:42 EDT 2017
Rustom Mody <rustompmody at gmail.com> writes:
> On Tuesday, September 5, 2017 at 1:44:24 AM UTC+5:30, Ben Bacarisse wrote:
>> Rustom Mody writes:
>>
>> > Here is some code I (tried) to write in class the other day
>> >
>> > The basic problem is of generating combinations
>> <snip>
>> > Now thats neat as far as it goes but combinations are fundamentally sets
>> > not lists
>> >
>> > So I thought python would do a better job
>> > I tried translating it to python and sets but it turned out more annoying than
>> > helpful
>> > Can someone improve it??
>> >
>> > The straightforward translation of the above
>> > Which is ok so far
>> >
>> >
>> > def c(n,r):
>> > if r == 0:
>> > return [[]]
>> > elif len(n) == 0:
>> > return []
>> > else:
>> > return [[n[0]] + l for l in c(n[1:],r-1)] + c(n[1:],r)
>> >
>> >
>> > Now to go from returning list of lists to set of sets:
>>
>> def cs(n, r):
>> if r == 0:
>> return [set()]
>> elif len(n) == 0:
>> return []
>> else:
>> return [set([n[0]]) | l for l in cs(n[1:], r-1)] + cs(n[1:], r)
>>
>> ?
>>
>> It's not so neat if you also want n to be a set rather than a list
>> because the set equivalents of n[0] and n[1:] are a but more complex but
>> it's not that bad:
>>
>> def css(n,r):
>> if r == 0:
>> return [set()]
>> elif len(n) == 0:
>> return []
>> else:
>> rest = n.copy()
>> e = rest.pop()
>> return [set([e]) | l for l in css(rest, r-1)] + css(rest, r)
>
> Trying out your code Ben…
>
>>>> css({1,2,3,4}, 2)
> [set([1, 2]), set([1, 3]), set([1, 4]), set([2, 3]), set([2, 4]), set([3, 4])]
>
>>>> type(css({1,2,3,4}, 2))
> <type 'list'>
>
> Whereas with the cs I earlier gave:
>>>> cs(frozenset([1,2,3,4]), 2)
> frozenset([frozenset([2, 4]), frozenset([3, 4]), frozenset([2, 3]),
> frozenset([1, 3]), frozenset([1, 2]), frozenset([1, 4])])
If you want a (frozen) sets of sets I'd just the code to
def css(n, r):
if r == 0:
return frozenset({frozenset()})
elif len(n) == 0:
return frozenset()
else:
rest = set(n)
e = rest.pop()
return frozenset([frozenset([e])
| l for l in list(css(rest, r-1))]) | css(rest, r)
>>> css(frozenset({1,2,3,4}), 2)
frozenset({frozenset({2, 4}), frozenset({3, 4}), frozenset({2, 3}),
frozenset({1, 3}), frozenset({1, 2}), frozenset({1, 4})})
The switch from lists (using +) and frozen sets using | is the most
obvious change, but if the top-level argument might itself be a
frozenset then the copy must be changed to a set constructor so that pop
will work.
<snip>
--
Ben.
More information about the Python-list
mailing list