if line not startswith item from a list - python

I would like to know how to take those items from a list that don't start like some of the items from another list.
I want to make something like:
list_results = ['CONisotig124', '214124', '2151235', '235235', 'PLEisotig1235', 'PLEisotig2354', '12512515', 'CONisotig1325', '21352']
identifier_list=['CON','VEN','PLE']
for item in list_results:
if not item.startswith( "some ID from the identifier_list" ):
print item
So, how do I say:
if not item.startswith( "some ID from the identifier_list" ):

str.startswith() can take a tuple of strings to test for:
prefix can also be a tuple of prefixes to look for.
Use this together with a list comprehension:
identifier_list = ('CON', 'VEN', 'PLE') # tuple, not list
[elem for elem in list_results if not elem.startswith(identifier_list)]
Demo:
>>> list_results = ['CONisotig124', '214124', '2151235', '235235', 'PLEisotig1235', 'PLEisotig2354', '12512515', 'CONisotig1325', '21352']
>>> identifier_list = ('CON', 'VEN', 'PLE') # tuple, not list
>>> [elem for elem in list_results if not elem.startswith(identifier_list)]
['214124', '2151235', '235235', '12512515', '21352']

that's pretty straight-forward, you almost got it:
for item in list_results:
bad_prefix = False
for id in identifier_list:
if item.startswith(id):
bad_prefix = True
break
if not bad_prefix:
print item

Related

python 3 list comprehension with if clause referring to list

I have this code:
xtralist = ["df","cvbcb","df"]
kont=[]
b = Counter(xtralist)
for item in xtralist:
if item not in kont:
print(b[item]
kont.append(item)
The kont list is only there to see if the printing for that item has been done before. It works but is too slow for large xtralist, so I tried this:
[(print(b[item] and kont.append(item)) for item in xtralist if item not in kont]
which doesnt work. I am sure there are smarter ways, but how can I do this with list comprehension?
set is indeed the way to go. If the order is important though, you'll need to use a list and a set:
xtralist = ["df","cvbcb","df"]
already_seen = set()
for item in xtralist:
if item not in already_seen:
print(item)
already_seen.add(item)
It outputs:
df
cvbcb
If you want to display the number of occurences, you can modify your code slightly:
from collections import Counter
xtralist = ["df","cvbcb","df"]
kont = set()
b = Counter(xtralist)
for item in xtralist:
if item not in kont:
print("%s * %d" % (item, b[item]))
kont.add(item)
It outputs:
df * 2
cvbcb * 1
All you need to do is enclose your xtralist into a set so that it doesn't have any duplicate elements, and then just print each item in the set:
xtralist = ["df", "cvbcb", "df"]
print('\n'.join(set(xtralist)))
df
cvbcb
To dig into the code a little bit, check out each step:
>>> xtralist = ["df", "cvbcb", "df"]
>>> xtralist
['df', 'cvbcb', 'df']
>>> set(xtralist)
{'df', 'cvbcb'}
>>> '\n'.join(set(xtralist))
'df\ncvbcb'
>>> print('\n'.join(set(xtralist)))
df
cvbcb
However, note that a set is unordered, so if order is important, you'll have to iterate through your list; a little modification to what you were trying would work; you don't need a Counter at all:
xtralist = ["df", "cvbcb", "df"]
kont = []
for item in xtralist:
if item not in kont:
print(item)
kont.append(item)
df
cvbcb

Group elements of a list based on repetition of values

I am really new to Python and I am having a issue figuring out the problem below.
I have a list like:
my_list = ['testOne:100', 'testTwo:88', 'testThree:76', 'testOne:78', 'testTwo:88', 'testOne:73', 'testTwo:66', 'testThree:90']
And I want to group the elements based on the occurrence of elements that start with 'testOne'.
Expected Result:
new_list=[['testOne:100', 'testTwo:88', 'testThree:76'], ['testOne:78', 'testTwo:88'], ['testOne:73', 'testTwo:66', 'testThree:90']]
Just start a new list at every testOne.
>>> new_list = []
>>> for item in my_list:
if item.startswith('testOne:'):
new_list.append([])
new_list[-1].append(item)
>>> new_list
[['testOne:100', 'testTwo:88', 'testThree:76'], ['testOne:78', 'testTwo:88'], ['testOne:73', 'testTwo:66', 'testThree:90']]
Not a cool one-liner, but this works also with more general labels:
result = [[]]
seen = set()
for entry in my_list:
test, val = entry.split(":")
if test in seen:
result.append([entry])
seen = {test}
else:
result[-1].append(entry)
seen.add(test)
Here, we are keeping track of the test labels we've already seen in a set and starting a new list whenever we encounter a label we've already seen in the same list.
Alternatively, assuming the lists always start with testOne, you could just start a new list whenever the label is testOne:
result = []
for entry in my_list:
test, val = entry.split(":")
if test == "testOne":
result.append([entry])
else:
result[-1].append(entry)
It'd be nice to have an easy one liner, but I think it'd end up looking a bit too complicated if I tried that. Here's what I came up with:
# Create a list of the starting indices:
ind = [i for i, e in enumerate(my_list) if e.split(':')[0] == 'testOne']
# Create a list of slices using pairs of indices:
new_list = [my_list[i:j] for (i, j) in zip(ind, ind[1:] + [None])]
Not very sophisticated but it works:
my_list = ['testOne:100', 'testTwo:88', 'testThree:76', 'testOne:78', 'testTwo:88', 'testOne:73', 'testTwo:66', 'testThree:90']
splitting_word = 'testOne'
new_list = list()
partial_list = list()
for item in my_list:
if item.startswith(splitting_word) and partial_list:
new_list.append(partial_list)
partial_list = list()
partial_list.append(item)
new_list.append(partial_list)
joining the list into a string with delimiter |
step1="|".join(my_list)
splitting the listing based on 'testOne'
step2=step1.split("testOne")
appending "testOne" to the list elements to get the result
new_list=[[i for i in str('testOne'+i).split("|") if len(i)>0] for i in step2[1:]]

How do I get next element from list after search string match in python

Hi Friends I have a list where I'm searching for string and along with searched string I want to get next element of list item. Below is sample code
>>> contents = ['apple','fruit','vegi','leafy']
>>> info = [data for data in contents if 'fruit' in data]
>>> print(info)
['fruit']
I want to have output as
fruit
vegi
What about:
def find_adjacents(value, items):
i = items.index(value)
return items[i:i+2]
You'll get a ValueError exception for free if the value is not in items :)
I might think of itertools...
>>> import itertools
>>> contents = ['apple','fruit','vegi','leafy']
>>> icontents = iter(contents)
>>> iterable = itertools.dropwhile(lambda x: 'fruit' not in x, icontents)
>>> next(iterable)
'fruit'
>>> next(iterable)
'vegi'
Note that if you really know that you have an exact match (e.g. 'fruit' == data instead of 'fruit' in data), this becomes easier:
>>> ix = contents.index('fruit')
>>> contents[ix: ix+2]
['fruit', 'vegi']
In both of these cases, you'll need to specify what should happen if no matching element is found.
One way to do that is to iterate over the list zipped with itself.
Calling zip(contents, contents[1:]), allows the data variable to take on these values during the loop:
('apple', 'fruit')
('fruit', 'vegi')
('vegi', 'leafy')
in that order. Thus, when "fruit" is matched, data has the value ('fruit', 'vegi').
Consider this program:
contents = ['apple','fruit','vegi','leafy']
info = [data for data in zip(contents,contents[1:]) if 'fruit' == data[0]]
print(info)
We compare "fruit" to data[0], which will match when data is ('fruit', 'vegi').
This straightforward imperative approach worked for me:
contents = ['apple', 'fruit', 'vegi', 'leafy']
result = '<no match or no successor>'
search_term = 'fruit'
for i in range(len(contents)-1):
if contents[i] == search_term:
result = contents[i+1]
print result
Note that you don't specify what the behavior should be for 1) not finding the search term, or 2) finding a match at the end of the list.

How to compare string vs. list of lists in Python/Spyder 2.7

I have a list:
myList = [['first'],['second'], ['third']]
and a comparison string, myStr = 'first'
I want to return True if myStr exists in myList, else False.
Just for the simple example you have shown, run
[myStr] in myList
But you should probably make myList equal a flat list if each sublist contains only one item - myList = ['first', 'second', 'third']
Then you only need
myStr in myList
In Python 2.7:
str = "first"
array = [["first"], ["second"], ...]
def isInArray(string, array):
for subarray in array:
for element in subarray:
if element == string:
return True
return False
print isInArray(str, array)
Anyway, the array makes no sense: if each subarray has only one element, you should make it easier:
array = ["first", "second", ...]
You need to iterate over the list with the for loop just once so that you can access the sublists
myStr = 'first'
myList = [['first'],['second'], ['third']]
def str_in_list_of_lists(myStr, myList):
for i in myList:
if myStr in i:
return True
return False
print str_in_list_of_lists(myStr, myList)
Example in Python 2.7:
food = [["apples", "prunes", "peaches"], ["tea", "coffee", "milk"], ["biscuits", "bread", "chips"]]
*You can try different strings here to check True/False values*
find = raw_input("What do you want in food?")
def str_in_list_of_lists(a, b):
for i in food:
if find in i:
return True
return False
print str_in_list_of_lists(find, food)

match/search dict keys in elements of a list

I have a dictionary,
dct = {'slab1': {'name':'myn1', 'age':20}, 'slab2':{'name':'myn2','age':200}}
lst = {'/store/dir1/dir_slab1/tindy', '/store/dir2/dirslab2_fine/tunka','/store/dir1/dirslab3/lunku'}
How can I search for 'slab1', 'slab2' which are the keys of the dictionary in the list elements ? If there is a match, I would like to print the matched element and the 'age' from the dictionary. So, in the above example, I should get something like :
'/store/dir1/dir_slab1/tindy', 20
'/store/dir2/dirslab2_fine/tunka', 200
Thanks for any suggestion
>>> dct = {'slab1': {'name':'myn1', 'age':20}, 'slab2':{'name':'myn2','age':200}}
>>> lst = {'/store/dir1/dir_slab1/tindy', '/store/dir2/dirslab2_fine/tunka','/store/dir1/dirslab3/lunku'}
>>> for item in lst:
... for pattern in dct:
... if pattern in item:
... print "%s, %s" % (item, dct[pattern]["age"])
...
/store/dir1/dir_slab1/tindy, 20
/store/dir2/dirslab2_fine/tunka, 200
You can also use list comprehension notation to get pairs:
>>> [(item, dct[pattern]["age"]) for item in lst for pattern in dct if pattern in item]
[('/store/dir1/dir_slab1/tindy', 20), ('/store/dir2/dirslab2_fine/tunka', 200)]
P.S. There are some misunderstandings in your question (eg, list variable is not a list), but solution should look like this.

Categories

Resources