How can I check if number exists in list - python

I wish to check if a certain number is in a list, but I'm struggling with the if sentence. I have
possibilities = []
node = 1
edges = [['1', '1', '10'], ['1', '6', '7'], ['1', '16', '5'], ['1', '18', '6'], ['1', '19', '6'], ['2', '2', '10'], ['2', '5', '3']]
for i in edges:
if node in i[:-1]:
possibilities.append(i)
print(possibilities)
But I'm not getting any entries in possibilities. Is there something I'm missing, because I thought this should work.

You are confusing the data type int with data type string. Change the node to "1" instead of 1 and you are good to go.

You are trying to compare int data type with str data type. Try this:
possibilities = []
node = 1
edges = [['1', '1', '10'], ['1', '6', '7'], ['1', '16', '5'], ['1', '18', '6'], ['1', '19', '6'], ['2', '2', '10'], ['2', '5', '3']]
for i in edges:
if str(node) in i:
possibilities.append(i)
print(possibilities)

Related

How to retrieve the position of a list in a list of lists in python

A = [['0', '6', '4', '3'], ['0', '2', '8', '3'], ['0', '4', '1', '5'], ['0', '3', '2', '5']]
B = ['0', '4', '1', '5']
Say I want to find out at which line does B equal to the list. How do I write a solution for this?
The answer would be the third line.
I tried doing a for loop.
You can try list.index(element) to get the index of the element in the original list (A). In your terminology, to get the line just add one to the index.
line = A.index(B) + 1
you dont need use loops.you can get the element index by indexing.
A = [['0', '6', '4', '3'], ['0', '2', '8', '3'], ['0', '4', '1', '5'], ['0', '3', '2', '5']]
B = ['0', '4', '1', '5']
print(A.index(B))
>>> 2

Sample from list of lists until condition is met

I have a list of lists that I am randomly choosing a value from. The issue I am having now is that since the loop I wrote is using random.choice() there is the possibility that a given value won't be present, which will cause an error in downstream code. So I basically want to sample from this list of lists until the final list has at least one occurrence of each value (so at least one occurrence of 1-8).
Below is my current code and the output list for probe which doesn't include a single occurrence of 3 in this iteration, which will cause the subsequent code to fail.
Some restrictions I have:
The final list probe needs to be only 16 items.
One of the two values needs to be picked at each index because it codes for a later stimulus. So for example, probe[0] in this case needs to be either 7 or 6 and probe[15] needs to be either 3 or 2. But still with the condition that across all indexes, 1-8 appears at least once.
probe_list = [['7', '6'], ['5', '8'], ['3', '2'], ['1', '4'], ['7', '6'], ['1', '4'], ['5', '8'], ['7', '6'], ['1', '4'], ['3', '2'], ['7', '6'], ['1', '4'], ['7', '6'], ['1', '4'], ['5', '8'], ['3', '2']]
probe=[]
for i in range(len(probe_list)):
choose = random.choice(probe_list[i])
probe.append(choose)
probe = ['7', '8', '2', '1', '6', '1', '5', '6', '4', '2', '7', '4', '6', '4', '8', '2']
You could create a set, which contains all values which are already in the probe in the current "run". Then you could always check, whether the size of the set is 8. If you begin a new "run", then you have to clear() the set and the probe.
import random
probe_list = [['7', '6'], ['5', '8'], ['3', '2'], ['1', '4'], ['7', '6'], ['1', '4'], ['5', '8'], ['7', '6'], ['1', '4'], ['3', '2'], ['7', '6'], ['1', '4'], ['7', '6'], ['1', '4'], ['5', '8'], ['3', '2']]
probe=[]
while True:
contained=set()
probe = []
for i in range(len(probe_list)):
choose = random.choice(probe_list[i])
contained.add(choose)
probe.append(choose)
if len(contained) == 8:
break
print(probe, len(probe), len(set(probe)))
It would alway ensure, that the length of the probe is 16 and the number of unique items in the probe is 8.
For example the output:
['7', '5', '2', '4', '6', '1', '8', '7', '1', '3', '6', '4', '6', '1', '5', '3'] 16 8

Remove an element in Python list with partial word in list

I have a list that looks like this and I've tried the following code and nothing seems to work. My list called "ss" looks like this and I'm trying to remove any elements with "Sheet" in list:
ss = ['14', '13', '11', '10', '9', '8', '6', '3', '2', '1', '0', '7', '4', '12', '5', 'Sheet12', 'Sheet1']
I have tried variations of this and they do nothing:
ssnew = list(filter( lambda s: not (s[0:4]=="Sheet"), ss))
or,
newss = {ss.replace("Sheet","")for x in ss}
I need my new list newss to look like this -->
newss = ['14', '13', '11', '10', '9', '8', '6', '3', '2', '1', '0', '7', '4', '12', '5']
Use a comprehension:
>>> [i for i in ss if not i.startswith('Sheet')]
['14',
'13',
'11',
'10',
'9',
'8',
'6',
'3',
'2',
'1',
'0',
'7',
'4',
'12',
'5']
Since you do mention that list elements should not contain "Sheet" with no other requirement, then this list comprehension is correct:
print([x for x in ss if 'Sheet' not in x])
Another solution would be:
lst = [i for i in ss if i.isdigit()]
print(lst)

Combine/group/merge partially the list of lists by equal first field, joining second field in string and writing in other fields same data

Example, I have list, I can sort it by first 2 fields, that's ok:
import operator
list = [
['1', '2', '3'],
['1', '5', '6'],
['2', '8', '9', '8', '17'],
['2', '3', '5', '3'],
['1', '14', '89', '34', '15'],
]
sorted_list = sorted(list, key=operator.itemgetter(0, 1))
getting:
['1', '14', '89', '34', '15']
['1', '2', '3']
['1', '5', '6']
['2', '3', '5', '3']
['2', '8', '9', '8', '17']
So, what I need - is to combine those lists by 1st field, in first step it would be '1' from [0][0], [0][1], [0][2], then I join second field with something like comma: "14:2:5" and I don't care, which part of those 3 list I append then, so, after '|' it can be any of:
['1', '14:2:5',| '89', '34', '15']
['1', '14:2:5',| '3']
['1', '14:2:5',| '6']
(in most cases data after '|' will match for first field)
In the end, I want something like:
['1', '14:2:5', '89', '34', '15']
['2', '3:8', '5', '3']
I'm currently into some sort of for loop and getting IndexError all the way :-(
I feel it should be much easier pythonic way.
Don't get yet how to find this algorithm and how it called. Something like list of lists reduce-map-shrink-normalization elements, appending another by element values?
Thanks a lot for helping, things in python still surprise me, how cool it could be done, in the end from all answers, for python 3:
# -*- coding: utf-8 -*-
import operator
import itertools
from natsort import humansorted
list_to_sort = [
['1', 'A', '3'],
['1', '5', '6'],
['1', '1', '10', '11', '12'],
['t', 'S', '7', '0asdf'],
['2', '8', '9', '8', '17'],
['2', '705', '5', '3'],
['2', 'checks', 'df', '1'],
['1', '14', '89', '34', '15'],
]
sorted_list = humansorted(list_to_sort, key=operator.itemgetter(0, 1))
grouped = [list(g) for k, g in itertools.groupby(sorted_list, key=lambda x: x[0])]
out = [[gg[0][0], ':'.join([g[1] for g in gg])] + gg[0][2:] for gg in grouped]
for elem in out:
print(elem)
Once you've sorted your list so that your first-field groups are contiguous, you can use itertools.groupby to do the heavy lifting:
>>> grouped = [list(g) for k,g in groupby(sorted_list, key=lambda x: x[0])]
>>> grouped
[[['1', '14', '89', '34', '15'], ['1', '2', '3'], ['1', '5', '6']], [['2', '3', '5', '3'], ['2', '8', '9', '8', '17']]]
>>> out = [[gg[0][0], ':'.join([g[1] for g in gg])] + gg[0][2:] for gg in grouped]
>>> out
[['1', '14:2:5', '89', '34', '15'], ['2', '3:8', '5', '3']]
You can use a dictionary to preserve the sublist with common first item then use a list comprehension with zip and join to create the desire result:
>>> d={}
>>>
>>> for i,*j in sorted_list:
... d.setdefault(i,[]).append(iter(j))
...
>>> [[i,':'.join(next(zip(*j)))]+next(j)[1:] for i,j in d.items()]
[['1', '14:2:5', '89', '34', '15'], ['2', '3:8', '5', '3']]
But note that this code have been written in python 3. if you are in python 2 you can use itertools.izip instead of zip and for creating the dictionary you can do :
>>> for i in sorted_list:
... d.setdefault(i[0],[]).append(iter(i[1:]))
You could do it with a pair of functions as shown below. The first one, named grouper, is a generator function which are often useful when there's a need to produce intermediate results from a process requires non-trivial amount of initialization and/or housekeeping to be done before multiple intermediate results are returned.
As #Ashwini Chaudhary pointed out in a comment, you were sorting the fields lexicographically, not numerically, in your code, so that issue was also corrected.
import operator
def grouper(a_list):
if a_list:
sorted_list = sorted(a_list,
key=lambda e, get_items=operator.itemgetter(0, 1):
map(int, get_items(e)))
g = [sorted_list[0]]
for x in sorted_list[1:]:
if x[0] == g[-1][0]:
g.append(x)
else:
yield g
g = [x]
yield g
def combiner(a_list):
return [[g[0][0], ':'.join(e[1] for e in g)] + g[0][2:]
for g in grouper(a_list)]
a_list = [
['1', '2', '3'],
['1', '1', '10', '11', '12'], # element added to test sorting
['1', '5', '6'],
['2', '8', '9', '8', '17'],
['2', '3', '5', '3'],
['1', '14', '89', '34', '15'],
]
print(combiner(a_list))
Output:
[['1', '1:2:5:14', '10', '11', '12'], ['2', '3:8', '5', '3']]

Multiple sorting in Python

I have an array with these datas:
[['1', '7', '14'], ['1', '1', '3'], ['1', '12', '3'], ['2', '3', '1'], ['1', '4', '9']]
I like to sort it (multiple):
>>> sorted(datas,key=lambda x:(x[0], x[1]))
[['1', '1', '3'], ['1', '12', '3'], ['1', '4', '9'], ['1', '7', '14'], ['2', '3', '1']]
but after sorted as it seems the 12 < 4. It should be:
[['1', '1', '3'], ['1', '4', '9'], ['1', '7', '14'], ['1', '12', '3'], ['2', '3', '1']]
Any idea? I need not natural sorting.
There is not wrong with sorted behaviour. Your data are lists of string, so it's doable.
>>> data = ['1', '12', '3', '2']
>>> sorted(data)
['1', '12', '2', '3']
If you want to sort as integer, it must be converted.
>>> sorted(data)
['1', '12', '2', '3']
>>> data = [['1', '7', '14'], ['1', '1', '3'], ['1', '12', '3'], ['2', '3', '1'], ['1', '4', '9']]
>>> sorted(data, key=lambda x: map(int, x))
[['1', '1', '3'], ['1', '4', '9'], ['1', '7', '14'], ['1', '12', '3'], ['2', '3', '1']]
Convert x[1] to int(x[1]):
sorted(d,key=lambda x:(int(x[0]), int(x[1])))
Output:
[['1', '1', '3'], ['1', '4', '9'], ['1', '7', '14'], ['1', '12', '3'], ['2', '3', '1']]
You are comparing strings, not ints. Therefor the order you get is the lexicographical order.
If you convert to int first
sorted(data, key=lambda x:(int(x[0]), int(x[1])))
you will get the desired result
[['1', '1', '3'], ['1', '4', '9'], ['1', '7', '14'], ['1', '12', '3'], ['2', '3', '1']]
Currently your sort is working on tuples string values. String values are determined similarly to any other iterable. When it compares two strings, it goes character by character from left-to-right or index 0 to index n-1 where n is the length of the iterable, until it finds one character that is larger than another. so when comparing '12' and '4', it notices that '4' is greater than '1' so it finishes right there. This system of ordering is known as lexicographical order.
To see the "value" of a character (In Python, a character is just a string of length 1), just use the ord function:
>>> ord('1')
49
>>> ord('4')
52
And to validate that the string '12' is indeed less than '4' because ord('1') < ord('4'):
>>> '12' < '4'
True
If you want to sort by the integer values of the strings, you have to convert the strings to ints by using the built-in int constructor.
sorted(datas,key=lambda x: (int(x[0]), int(x[1]))
Or if you want to cleanly handle iterables of all sizes, simply use a tuple-generator for the key:
sorted(datas,key=lambda x: tuple(int(e) for e in x))

Categories