dealing with an empty list inside a list - python

I have a list which looks something like this:
mylist = ([(0.1, 0.5),(0.4, 1.0)], [(0.2, 0.4),(0.15, 0.6)], None, [(0.35, 0.8),(0.05, 1.0)])
What I would like to know is how do I check for the empty entry or None in the list and if there is one then it should continue further ignoring it. Something like,
if mylist == something :
do this
if mylist == [] or () or None :
ignore and continue
I am not able to put that into a code. Thank you.

Basically, in python
[], (), 0, "", None, False
all of these means that the value is False
Therefore:
newList = [i for i in myList if i] # this will create a new list which does not have any empty item
emptyList = [i for i in myList if not i] # this will create a new list which has ONLY empty items
or as you asked:
for i in myList:
if i:
# do whatever you want with your assigned values
else:
# do whatever you want with null values (i.e. [] or () or {} or None or False...)
and then you can do whatever you want with your new list :)

for sublist in mylist:
if sublist is None:
#what to do with None
continue
elif not sublist and isinstance(sublist, list):
#what to do if it's an empty list
continue
elif not isinstance(sublist, list):
#what to do if it's not a list
continue
#what to do if it's a list and not empty
Alternatively, you could leave out the 'continues' and put the general case in an else clause, only check for some of the possible circumstances, or nest the ifs.
Generally, if you knew you'd only get None or a container, just if not sublist: continue is adequate to ignore empty containers and None. To filter these values out of the list, do
mylist = [sublist for sublist in mylist if sublist]
Edit: You can't do this in the update function. You should pre-filter the list. Where you have
mylist = oldlist[:]
replace it with
mylist = [sublist for sublist in oldlist if sublist]
If the row name a, b, or whatever is there, but the rest is empty / None, then do
mylist = [sublist for sublist in oldlist if sublist[1]]
and this will filter on the truth value of the 2nd item intead of the first item / row title.

I will just do this:
for x in mylist:
if not x:
continue
#--> do what you want to do
but I have to say the first answer with comprehension list is more clean unless you need to do a complicated stuff inside the for statement.

How about this piece of code:
for x in mylist:
if x is None or x == [] or x == ():
continue
else:
do this

Related

I want to check for a specific element in a sublist and remove repeated sublists with the same element in python

i have this
lst = [['100','LA'],['101','NY'],['100','NC']]
lst2 = []
i need to check if there's any 100,101,etc repeated and remove the repeated numbers. So the second list would look like this
lst2=[['100','LA'],['101','NY']]
because the 100 was already added once in that second list
A quick and dirty way to do this is using a generic uniqueness filter:
def uniqueness(iterable,key=lambda x:x):
seen = set()
for item in iterable:
fitem = key(item)
if fitem not in seen:
yield item
seen.add(fitem)
You can then use it like:
list2 = list(uniqueness(lst,key=lambda x:x[0]))
If you do not specify, the filter will assume the entire element (but this will fail here, because list is not hashable).
An answer without lambda's.
nmbrs = [n for n, city in lst]
lst2 = [x for i, x in enumerate(lst) if x[0] not in nmbrs[:i]]

Python - add information to items in a list thereby creating a list of tuples

I have a list:
list1 = [1,2,3]
I'm looking up info for each item in the list via some arbitrary function, and want to add the results so the list becomes:
list1 = [(1,a),(2,b),(3,x)]
How to best accomplish this in Python3?
for item in list1:
newinfo = some_arbitrary_function(item)
item = (item, newinfo)
Does not appear to work.
You need a list comprehension:
lst = [1,2,3]
result = [(item, function(item)) for item in lst]
Using list as a name is not a good idea, you'll shadow the original list builtin making it inaccessible later in your code.
In case you want to keep the reference to the original list:
lst[:] = [(item, function(item)) for item in lst]
It is not possible to assign a list item with the iteration variable (item in your case). In fact, there is nothing special about the variable item compared to an assignment with =. If the operation is intended to be in-place, you should do
for i, item in enumerate(list):
list[i] = (item, func(item))
Also, you should not name your list list, because it will hide the built-in type list.
It looks like you just want to change the values in the list to go from a single to a tuple containing the original value and the result of some lookup on that value. This should do what you want.
zzz = [1,2,3]
i = 0
for num in zzz:
zzz[i] = (num, somefunc(num))
i += 1
running this
zzz = [1,2,3]
i = 0
for num in zzz:
zzz[i] = (num, 8)
i += 1
gives the results zzz = [(1,8), (2,8), (3,8)]
If you have list1 = [1,2,3] and list2 = [x,y,z], zip(list1, list2) will give you what you're looking for. You will need to iterate over the first list with the function to find x, y, z and put it in a list.
zip(list1, list2)
[(1, x), (2, y), (3, z)]

Delete item from list upon a condition

I have a list of lists of tuples of integers.
ls = [[(a_1, a_2), (b_1, b_2)], [(c_1, c_2), (d_1, d_2), (e_1, e_2)], ...]
And I need to delete every item of ls that contains a tuple whose second entry is equal to a predetermined integer.
I tried this:
for item in ls:
for tpl in item:
if tpl[1] == m:
ls.remove(item)
But for some reason, this only removes a few of the list items but not all containing a tuple with second entry = m.
Use a list comprehension:
ls = [item for item in ls if all(tuple[1] != m for tuple in item)]
Or use a filter:
ls = filter(lambda item: all(tuple[1] != m for tuple in item),ls)
Code sucks and we need less of it - here's as sparse as it gets.
[l for l in ls if m not in [i[1] for i in l]]
The best way to filter a list in python is to use a list comprehension:
filtered = [item for item in ls if not(contains_m(item))]
And then all you need is a function that can tell if an item contains m, for example:
def contains_m(item):
return any([tpl[1] == m for tpl in item])
Removing an itme from list is not a good idea while iterating though it.
Try that (if where are talking Python here)
ls = [[('a_1', 'a_2'), ('b_1', 'b_2')], [('c_1', 'c_2'), ('d_1', 'd_2'), ('e_1', 'e_2')]]
m='c_2'
print [ x for x in ls if not [ y for y in x if y[1]==m ]]
Python's list iterator is lazy. This means that when you remove an item from the list, it will skip the next item. For example, say you want to remove all ones from the following list:
[1, 1, 2]
Your for loop starts at index 0:
[1, 1, 2]
^
It removes the element and moves on:
[1, 2]
^
This example is just to help illustrate the issue. One simple workaround is to loop backwards using the index:
for ind in range(len(ls)-1, -1, -1):
item = ls[ind]
for tpl in item:
if tpl[1] == m:
del ls[ind]
break # You can end the inner loop immediately in this case
Another way is to make a copy of the list to iterate over, but remove from the original:
for item in ls[:]:
for tpl in item:
if tpl[1] == m:
ls.remove(item)
break
The last approach can be simplified into creating an output list that contains only the elements that you want. This is easiest to do with a list comprehension. See #AlexeySmirnov 's answer for the best way to do that.

python - keep "other" element in a list under if conditions

I have a list of strings like the following:
L = ['aa','bb','cc']
I would like to apply an if condition on its elements to check if multiple strings are in it, and then keep only one element as result. The pseudo-code I'm trying to implement is:
if 'aa' in L AND 'cc' in L:
return the third element (i.e. 'bb')
else:
return 'aa'
So far I've been working with a list comprehension like:
return = ['aa' if elem != 'aa' and elem != 'cc' else elem for elem in L][0]
But it doesn't work as expected.
EDIT:
Fixed return as element and not a list.
I don't think you can do this with a single list comprehension. How about:
L = ['aa','bb','cc']
if "aa" in L and "cc" in L:
result = [item for item in L if item != "aa" and item != "cc"][0]
else:
result = "aa"
return result
Or return [item for item in L if item != "aa" and item != "cc"][0] if "aa" in L and "cc" in L else "aa" if you insist on doing it in one line.
You could find the difference between your lists using sets:
l = ['aa','bb','cc']
k = ['aa','cc']
if len(list(set(l) - set(k))) == 1:
return list(set(l) - set(k))
else:
return l[0]
If they return exactly one element return that, otherwise the first element of l.

Test for list membership and get index at the same time in Python

It seems silly to write the following:
L = []
if x in L:
L[x] = something
else:
L[x] = something_else
Doesn't this perform the look-up for x twice? I tried using index(), but this gives an error when the value is not found.
Ideally I would like to say like:
if x is in L, save that index and:
...
I can appreciate that this might be a beginner python idiom, but it seems rather un-search-able. Thanks.
Another option is try/except:
d = {}
try:
d[x] = something_else
except KeyError:
d[x] = something
Same result as your code.
Edit: Okay, fast moving target. Same idiom for a list, different exception (IndexError).
Do you mean you want setdefault(key[, default])
a = {}
a['foo'] # KeyError
a.setdefault('foo', 'bar') # key not exist, set a['foo'] = 'bar'
a.setdefault('foo', 'x') # key exist, return 'bar'
If you have a list you can use index, catching the ValueError if it is thrown:
yourList = []
try:
i = yourList.index(x)
except ValueError:
i = None
Then you can test the value of i:
if i is not None:
# Do things if the item was found.
I think your question confused many because you've mixed your syntax between dict and list.
If:
L = [] # L is synonym for list and [] (braces) used to create list()
Here you are looking for a value in a list, not a key nor a value in a dict:
if x in L:
And then you use x seemingly intended as a key but in lists it's an int() index and doing if x in L: doesn't test to see if index is in L but if value is in L:
L[x]=value
So if you intend to see if a value is in L a list do:
L = [] # that's a list and empty; and x will NEVER be in an empty list.
if x in L: # that looks for value in list; not index in list
# to test for an index in a list do if len(L)>=x
idx = L.index(x)
L[idx] = something # that makes L[index]=value not L[key]=value
else:
# x is not in L so you either append it or append something_else
L.append(x)
If you use:
L[x] = something together with if x in L: then it would make sense to have a list with only these values: L=[ 0, 1, 2, 3, 4, ...] OR L=[ 1.0, 2.0, 3.0, ...]
But I'd offer this:
L = []
L.extend(my_iterable)
coder0 = 'farr'
coder1 = 'Mark Byers'
if coder0 not in L:
L.append(coder1)
Weird logic

Categories