Recursive List Comprehension in Python

Recursive list comprehension in Python?

No, there's no (documented, solid, stable, ...;-) way to refer to "the current comprehension". You could just use a loop:

res = []
for x in nums:
if x not in res:
res.append(x)

of course this is very costly (O(N squared)), so you can optimize it with an auxiliary set (I'm assuming that keeping the order of items in res congruent to that of the items in nums, otherwise set(nums) would do you;-)...:

res = []
aux = set()
for x in nums:
if x not in aux:
res.append(x)
aux.add(x)

this is enormously faster for very long lists (O(N) instead of N squared).

Edit: in Python 2.5 or 2.6, vars()['_[1]'] might actually work in the role you want for self (for a non-nested listcomp)... which is why I qualified my statement by clarifying there's no documented, solid, stable way to access "the list being built up" -- that peculiar, undocumented "name" '_[1]' (deliberately chosen not to be a valid identifier;-) is the apex of "implementation artifacts" and any code relying on it deserves to be put out of its misery;-).

Recursion with List Comprehension

A list comprehension

a = [b for b in c]

is equivalent to

a=[]
for b in c :
a.append(b)

So this:

a=[digit + bits for digit in bit_str(1, s) for bits in bit_str(n-1, s)]

would be the same as

a=[]
for bits in bit_str(n-1,s):
for digit in bit_str(1,s):
a.append(digit+bits)

Demo:

def bit_str(n, s):
if n == 1:
return s
return [digit + bits for digit in bit_str(1, s) for bits in bit_str(n-1, s)]

def bit_str2(n, s):
if(n==1):
return s
a=[]
for digit in bit_str2(1,s) :
for bits in bit_str2(n-1,s) :
a.append(digit+bits)
return a

print bit_str(3,'abc')
print bit_str2(3, 'abc')

Output:

$ python p.py 
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']

Recursive Function to List Comprehension

You can simplify the loop by moving your base case out of it, which in turn makes it easier to see how to turn it into a comprehension:

def _dict_to_map(d):
if not isinstance(d, dict):
return d
return [(k, _dict_to_map(v)) for k, v in d.items()]

Can I flatten a list using recursive function and list comprehension?

You can though it is a little strange:

def fun_d(x):
return [i for e in x for i in (fun_d(e) if isinstance(e,list) else [e])]

In[] :
l=[1,[2,3],[4,5,[6,7,8,9]]]
fun_d(l)

Out[]:
[1, 2, 3, 4, 5, 6, 7, 8, 9]

You may want to use Sequence rather than list so other types of sequences would also be flattened.

from typing import Sequence

def fun_d(x):
return [i for e in x for i in (fun_d(e) if isinstance(e, Sequence) and not isinstance(e, str) else [e])]

A named lambda is trivial, for a truly anonymous lambda you can use a y-combinator

And just to show how ridiculous this is, an anonymous recursive lambda:

In []:
lis = [1,[2,3],[4,5,[6,[7,8],9]]]
(lambda f: f(f))(lambda f: (lambda fun_d: lambda x: [i for e in x for i in (fun_d(e) if isinstance(e, list) else [e])])(lambda x: f(f)(x)))(lis)

Out[]:
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Python recursive list comprehension to iterative approach

There are two issues in your code.

First, as pointed out by @MisterMiyagi, you switched the loops. In a list comprehension, loops are read from left to right. You should write the regular loops like this:

for digit in bitStr2(1, s):
for bits in bitStr2(n - 1, s):
...

Second, a list comprehension produces... a list. You have to store the elements in a list:

...
result = []
for digit in bitStr2(1, s):
for bits in bitStr2(n - 1, s):
result.append(digit + bits)
return result

(Conversely: never use a list comprehension if you don't want to produce a list.) And you don't have to handle differently the n = 1 case. Full code:

def bitStr2(n, s):
if n == 1:
return s
result = []
for digit in bitStr2(1, s):
for bits in bitStr2(n - 1, s):
result.append(digit + bits)
return result

Note that for digit in bitStr(1, s) is equivalent to for digit in s. I don't see why you call the method bitStr in this case, since you already know the result.

python: recursive expanding list comprehension

You could use itertools.product if you are allowed to :

n=3
list(itertools.product(*[list(range(i)) for i in reversed(range(1, n+1))]))

python--recursive list comprehension to apply lstrip on a list

Try this:

>>> f = ['sum_','count_','per_']
>>> d = ['fav_genre','sum_fav_event','count_fav_type','per_fav_movie']
>>> [s[len(([p for p in f if s.startswith(p)]+[""])[0]):] for s in d]
['fav_genre', 'fav_event', 'fav_type', 'fav_movie']

I believe this handles all of the cases as intended.



Related Topics



Leave a reply



Submit