Apply a lambda function while appending to a list - python

Imagine a one dimensional array 'inter' and an empty list 'visual_pred'. I want to iterate over all elements in the array and append each element to my list while adding the element with the list's last entry.
My code looks like this:
visual = []
for x in inter:
if x > 0:
visual.append(lambda x: x + visual[-1])
else:
visual.append(visual[-1])
After executing the code all entries in my list 'inter' looks like this:
function __main__.lambda(x)
What is the problem here and how can I challenge it?

What you're doing here is appending the lambda function itself to your list and not the lambda functions output. I don't actually see why you need a lambda here anyway. This does what you want.
visual = []
for x in inter:
if x > 0:
visual.append(x + visual[-1])
else:
visual.append(visual[-1])

As BeanBagTheCat pointed out, you're appending the lambda function itself to your list and not the lambda functions output. You can write the same code by BeanBagTheCat in one line using list-comprehension as follows:
visual = [x + visual[-1] if x > 0 else visual[-1] for x in inter]

Related

List comprehensions in Python "freezing" Jupyter notebook

When I run the code below in Jupyter notebook, my "kernel" freezes (I get an asterisk between the square brackets like so: [*]):
x = [1,2,3,4]
for num in x:
x.append(num**2)
Why doesn't this code "append" the exponentiated numbers to the end of x?
The code below works and I understand why, but why doesn't the code above work:
x = [1,2,3,4]
out = []
for num in x:
out.append(num**2)
print(out)
You are iterating over a list, and in every iteration you append a new element to the list, so the iteration is never going to end.
To see what's happening, change your code to this:
import time
x = [1,2,3,4]
for num in x:
x.append(num**2)
time.sleep(0.5)
print(x)
If you know what you are doing, you can avoid this kind of "dynamic iteration" with the [:] trick:
x = [1,2,3,4]
for num in x[:]:
x.append(num**2)
This way you are iterating over x[:], not the growing x, in effect it's like you are iterating over a snapshot of x.
More concisely, you could use a list comprehension as follows:
x = [1,2,3,4]
x_squared = [elem**2 for elem in x]
x.extend(x_squared)

Getting value from a list corresponding to another list

I have a list containing:
NewL = [(1.1,[01,02]),(1.2,[03,04]),(1.3,[05,06])]
and i used enumerate to obtain the list as above where the square brackets containing [01,02],[03,04] and [05,06] are generally obtained from another list. I'll show it just in case:
L = [[01,02],[03,04],[05,06]]
and initially the output list is just:
OutputList = [1.1,1.2,1.3]
i used enumerate on both of this list to get what i have as the first list i've written above.
The problem i'm facing now is, let's say i want to only output the value for [05,06] which is 1.3 from the NewL. How would i do that? I was thinking of something like:
for val in NewL:
if NewL[1] == [05,06]:
print NewL[0]
but it's totally wrong as cases might change where it's not necessary always be [05,06] as it can be obtaining value for [03,04] and [01,02] too. I'm pretty new using enumerate so I'll appreciate any help for this.
The for loop should like this:
for val in NewL:
if val[1] == [5,6]:
print val[0]
It will print 1.3
I'm not sure I understand the question, so I will extrapolate what you need:
Given your 2 intial lists:
L = [[01,02],[03,04],[05,06]]
OutputList = [1.1,1.2,1.3]
you can generate your transformed list using:
NewL = list(zip(OutputList, L))
then, given 1 item from L, if you want to retrieve the value from OutputList:
val = [x for x, y in NewL if y == [05,06]][0]
But it would be a lot easier to just do:
val = OutputList[L.index([05,06])]
Note that both those expressions will raise an IndexError if the searched item is not found

What do [] brackets in a for loop in python mean?

I'm parsing JSON objects and found this sample line of code which I kind of understand but would appreciate a more detailed explanation of:
for record in [x for x in records.split("\n") if x.strip() != '']:
I know it is spliting records to get individual records by the new line character however I was wondering why it looks so complicated? is it a case that we can't have something like this:
for record in records.split("\n") if x.strip() != '']:
So what do the brackets do []? and why do we have x twice in x for x in records.split....
Thanks
The "brackets" in your example constructs a new list from an old one, this is called list comprehension.
The basic idea with [f(x) for x in xs if condition] is:
def list_comprehension(xs):
result = []
for x in xs:
if condition:
result.append(f(x))
return result
The f(x) can be any expression, containing x or not.
That's a list comprehension, a neat way of creating lists with certain conditions on the fly.
You can make it a short form of this:
a = []
for record in records.split("\n"):
if record.strip() != '':
a.append(record)
for record in a:
# do something
The square brackets ( [] ) usually signal a list in Python.

Variation of suffix array in python

I'm relatively new to computer science, and I'm learning how to code in python. I'm trying to figure out how to make a function that takes a list and returns a list of suffixes from the inputted list, in order from shortest length to longest length. For example, entering
[3,4,2,-9,7,6,1]
to the function would return
[[],[1],[6,1],[7,6,1],[-9,7,6,1],[2,-9,7,6,1],[4,2,-9,7,6,1],[3,4,2,-9,7,6,1]]
I've tried several approaches, but so far I'm not having much luck. Here is what I have so far:
def h(m):
newlist = []
x = 0
y = (len[m])-1
while x in range(y):
sublist = []
sublist = sublist + m[x:y]
newlist.append(sublist)
x += 1
return new list
When I try to run the function by entering something like
a = [3,4,2,-9,7,6,1]
h(a)
I get an error:
Traceback (most recent call last):
File "<pyshell#239>", line 1, in <module>
h(a)
File "<pyshell#238>", line 4, in h
y = (len[m])-1
TypeError: 'builtin_function_or_method' object has no attribute '__getitem__'
My objective with this bit of code was simply to create a the list of suffixes without sorting them by length. After I figure out how to create this new list I will add the sorting bit of the code. Keep in mind this is not a homework assignment. Any help would be greatly appreciated!
Possible solution is using list comprehension:
[l[i:] for i in range(len(l), -1, -1)]
This code uses slicing and list comprehension to simply return a list of slices from the end. Using your code, small modification is required - len is a function and not a dictionary, therefore you need to use the call operator () instead of subscript operator [].
y = len(m) - 1
That will not yield correct result though, because you will not get the last suffix and empty suffix. In order to cover these two, you will need to modify y or the loop to cover them
y = len(m) + 1
or better
while x in range(y + 1):
use parenthesis to get the length of the list:
y = len(m) - 1
Your error is in your len:
(len[m]) - 1
len is a function, and you can't index or slice or the what not. Do this instead:
y = len(m) - 1
There's also one other error:
return new list
Should be: (You can't have spaces in variables)
return newlist

Expanding elements in a list

I'm looking for a "nice" way to process a list where some elements need to be expanded into more elements (only once, no expansion on the results).
Standard iterative way would be to do:
i=0
while i < len(l):
if needs_expanding(l[i]):
new_is = expand(l[i])
l[i:i] = new_is
i += len(new_is)
else:
i += 1
which is pretty ugly. I could rewrite the contents into a new list with:
nl = []
for x in l:
if needs_expanding(x):
nl += expand(x)
else:
nl.append(x)
But they both seem too long. Or I could simply do 2 passes and flatten the list later:
flatten(expand(x) if needs_expanding(x) else x for x in l)
# or
def try_expanding(x)....
flatten(try_expanding(x) for x in l)
but this doesn't feel "right" either.
Are there any other clear ways of doing this?
Your last two answers are what I would do. I'm not familiar with flatten() though, but if you have such a function then that looks ideal. You can also use the built-in sum():
sum(expand(x) if needs_expanding(x) else [x] for x in l, [])
sum(needs_expanding(x) and expand(x) or [x] for x in l, [])
If you do not need random access in the list you are generating, you could also use write a generator.
def iter_new_list(old_list):
for x in old_list:
if needs_expanding(x):
for y in expand(x):
yield y
else:
yield x
new_list = list(iter_new_list(old_list))
This is functionally equivalent to your second example, but it might be more readable in your real-world situation.
Also, Python coding standards forbid the use of lowercase-L as a variable name, as it is nearly indistinguishable from the numeral one.
The last one is probably your most pythonic, but you could try an implied loop (or in py3, generator) with map:
flatten(map(lambda x: expand(x) if needs_expanding(x) else x, l))
flatten(map(try_expanding, l))

Categories

Resources