Lists in python 3 - python

So the problem is that I have a list which is made of pairs of numbers [ (0,0),(0,1)(0,2) ...etc and I would like to know how to delete from this list all pairs with the same numbers . List was created by this function.
l1 = []
def fun2(x,y):
for x in range(x+1):
for y in range(y+1):
l1.append((x,y))
return l1

You can avoid duplicate tuple elements while generating the list. Just add an if:
def fun2(x, y):
result = []
for a in range(x+1):
for b in range(y+1):
if a != b:
result.append((a,b))
return result
This could also be written more succinctly as a list comprehension:
result = [(a, b) for a in range(x+1) for b in range(y+1) if a != b]
Yet another option is to use itertools.product():
from itertools import product
result = [(a, b) for a, b in product(range(x+1), range(y+1)) if a != b]
Removing items afterwards is also possible with a list comprehension:
result = [pair for pair in result if pair[0] != pair[1]]
which creates a new list without the duplicate items then rebinds it to result. You can overwrite the list in place with:
result[:] = [pair for pair in result if pair[0] != pair[1]]

Method 1: Using list comprehnsion:
lst = [c for c in l1 if c[0] != c[1]]
Method 2: Building the list manually:
lst = []
for elem in l1:
if elem[0] != elem[1]:
lst.append(elem)

Related

return all indices of first elements in a list where subsequent values increase incrementally

Need to find indices very similar to here
But I have a list of multiple groups of incrementing values, e.g.
lst = [0,1,2,7,8,9]
Expected output: [0,3]
Version with a simple loop:
lst = [0,1,2,7,8,9]
prev = float('-inf')
out = []
for i,v in enumerate(lst):
if v!=prev+1:
out.append(i)
prev = v
out
Same thing with a list comprehension and zip:
out = [i for i, (a,b) in enumerate(zip([float('-inf')]+lst, lst)) if a+1!=b]
Variant with itertools.pairwise (python ≥3.10):
from itertools import pairwise
out = [0]+[i for i, (a,b) in enumerate(pairwise(lst), start=1) if a+1!=b]
output: [0, 3]

filter a list based on values in another list

list1 = ['a','b','c','d']
list2 = [1,0,1,0]
Given two lists like the above, I would like to obtain a third list whose values are ['a','c']
In other words, I'd like the target list to be the values from list1 where the corresponding element in list2 is 1.
As noted in the comments:
[i for i, j in zip(list1, list2) if j] would work.
Alternatively, if you were looking for something not so advanced:
list3 = []
for i in range(len(list1)):
if list2[i] == 1:
list3.append(list1[i])
Use enumerate function on second list to include index, which can be used for the first list.
[list1[i] for i, item in enumerate(list2) if item]
Generators can be nice if you have very long lists:
def filterfunc(a, b, keyvalue=1):
return (x for i, x in enumerate(a) if b[i] == keyvalue)
To get the whole sequence:
list(filterfunc(a, b))

Way without nested ifs to make a non-empty list of tuples with a common second element based on custom preference?

I have a list of tuples (a,b) with b equal to 1,2, or 3.
I want to make a list of a's where b == 2. If that list would be empty, I want to make a list of all a's where b == 1. Should that also be empty, then I want to make a list of all a's b == 3.
Right now I am using a nested if to accomplish this:
sizeTwo = [tup[0] for tup in tupleList if tup[1] == 2]
if sizeTwo:
targetList = sizeTwo
else:
sizeOne = [tup[0] for tup in tupleList if tup[1] == 1]
if sizeOne:
targetList = sizeOne
else:
sizeThree = [tup[0] for tup in tupleList if tup[1] == 3]
if sizeThree:
targetList = sizeThree
else:
print(f"Error: no matching items in tupleList")
Is there a "cleaner" way to accomplish this?
You can just build all three lists at once, then only keep the first non-empty list you find.
from collections import defaultdict
groups = defaultdict(list)
for a, b in tupleList:
groups[b].append(a)
targetList = groups[2] or groups[1] or groups[3]
del groups
if not targetList:
print("error")
This trades some efficiency for clarity.
Try this:
tuplist=[(2,3), (1,2), (5,1), (4,2)]
blist=[2,1,3]
newlist=[]
for b in blist:
for tup in tuplist:
if tup[1] == b:
newlist.append(tup)
if newlist:
break
print(newlist)
If I understand you correctly, this does what you want.

Splitting a list with a separator

I have written a function that gets two arguments: a list and one value that is present in the list previously given (sep). The purpose of the function is to split the given list and return multiple lists in list without the value that was specified in the second argument of the written fuction. So with def split_list([1,2,3,2,1],2) ---> result would be [[1],[3],[1]]. The functionality of spliting is good but the result keeps the second value of the function (sep) in the separated lists. I couldnt think of a way how to solve this problem. Thanks in advance
def split_list(l, sep):
occurence = [i for i, x in enumerate(l) if x == sep]
newlist=[]
newlist.append(l[:occurence[0]])
for i in range(0,len(occurence)):
j=i+1
if j < len(occurence):
newlist.append(l[occurence[i]:occurence[j]])
i+=1
newlist.append(l[occurence[-1]:])
return newlist
How about this:
def split_list(l, sep):
nl = [[]]
for el in l:
if el == sep:
nl.append([])
else:
# Append to last list
nl[-1].append(el)
return nl
Or with your method, by using the list of occurences:
def split_list(l, sep):
# occurences
o = [i for i, x in enumerate(l) if x == sep]
nl = []
# first slice
nl.append(l[:o[0]])
# middle slices
for i in range(1, len(o)):
nl.append(l[o[i-1]+1:o[i]])
# last slice
nl.append(l[o[-1]+1:])
return nl
you can split your list with below list comprehension and zip function :
>>> l=[1,2,3,2,1,8,9]
>>> oc= [i for i, x in enumerate(l) if x == 2]
>>> [l[i:j] if 2 not in l[i:j] else l[i+1:j] for i, j in zip([0]+oc, oc+[None])]
[[1], [3], [1, 8, 9]]
So for your function :
def split_list(l, sep):
occurence = [i for i, x in enumerate(l) if x == sep]
return [l[i:j] if sep not in l[i:j] else l[i+1:j] for i, j in zip([0]+occurence, occurence+[None])]
Use [list(x) for i, x in enumerate(l) if x != sep]

Removing items from a list in python

I am new to python and I'm wondering, how I would go about removing items from a list. Say I have the list:
a=[(102,12,0),(123,12,0),(124,12,1)]
I would like to remove the items that have a 0 at the end, so my list would end up like:
a = [(124,12,1)]
here:
a = [i for i in a if i[-1] != 0] #list comprehension (1 line) method.
"normal" way to do without list comprehension when the parent list is also destination list.
tmp = []
for i in a:
if i[-1] != 0:
tmp.append(i)
a = tmp
in action:
>>> a=[(102,12,0),(123,12,0),(124,12,1)]
>>> a = [i for i in a if i[-1] != 0]
>>> a
[(124, 12, 1)]
>>>
You can use list comprehensions
val[-1] would give you tuples with 0 at the end, assuming val is the variable used while iterating.
So, your code would be something like this:
a = [val for val in a if val[-1]]
Not as awesome as a one liner list comprehension but still do the trick :).
b = tuple
for tple in a:
b = b + tple
result = tuple
for val in set(b):
if val % 10 != 0:
result = result + (val,)

Categories