python 3 list comprehension with if clause referring to list - python

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

Related

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:]]

cycle "for" in Python

I have to create a three new lists of items using two different lists.
list_one = ['one', 'two','three', 'four','five']
list_two = ['blue', 'green', 'white']
So, len(list_one) != len(list_two)
Now I should create an algorithm(a cycle) which can do this:
[oneblue, twoblue, threeblue, fourblue, fiveblue]. Same for 'green' and 'white'.
I undestand that I should create three cycles but I don't know how.
I've tried to make a function like this but it doesn't works.
def mix():
i = 0
for i in range(len(list_one)):
new_list = list_one[i]+list_two[0]
i = i+1
return new_list
What am I doing wrong?
I think you might be looking for itertools.product:
>>> [b + a for a,b in itertools.product(list_two, list_one)]
['oneblue',
'twoblue',
'threeblue',
'fourblue',
'fiveblue',
'onegreen',
'twogreen',
'threegreen',
'fourgreen',
'fivegreen',
'onewhite',
'twowhite',
'threewhite',
'fourwhite',
'fivewhite']
You should do this
def cycle(list_one,list_two):
newList = []
for el1 in list_two:
for el2 in list_one:
newList.append(el2+el1)
return newList
There are a few problems with your code:
When you do a for loop for i in ...:, you do not need to initialize i (i = 0) and you should not increment it (i = i + 1) since Python knows that i will take all values specified in the for loop definition.
If your code indentation (indentation is very important in Python) is truly the one written above, your return statement is inside the for loop. As soon as your function encounters your return statement, your function will exit and return what you specified: in this case, a string.
new_list is not a list but a string.
In Python, you can loop directly over the list items as opposed to their index (for item in list_one: as opposed to for i in range(len(list_one)):
Here is your code cleaned up:
def mix():
new_list = []
for i in list_one:
new_list.append(list_one[i]+list_two[0])
return new_list
This can be rewritten using a list comprehension:
def mix(list_one, list_two):
return [item+list_two[0] for item in list_one]
And because list_two has more than one item, you would need to iterate over list_two as well:
def mix(list_one, list_two):
return [item+item2 for item in list_one for item2 in list_two]
return should be out of for loop.
No need to initialize i and increment it, since you are using range.
Also, since both list can be of variable length, don't use range. Iterate over the list elements directly.
def mix(): should be like def mix(l_one,l_two):
All above in below code:
def mix(l_one,l_two):
new_list = []
for x in l_one:
for y in l_two:
new_list.append(x+y)
return new_list
list_one = ['one', 'two','three', 'four','five']
list_two = ['blue', 'green', 'white']
n_list = mix(list_one,list_two)
print n_list
Output:
C:\Users\dinesh_pundkar\Desktop>python c.py
['oneblue', 'onegreen', 'onewhite', 'twoblue', 'twogreen', 'twowhite', 'threeblu
e', 'threegreen', 'threewhite', 'fourblue', 'fourgreen', 'fourwhite', 'fiveblue'
, 'fivegreen', 'fivewhite']
C:\Users\dinesh_pundkar\Desktop>
Using List Comprehension, mix() function will look like below:
def mix(l_one,l_two):
new_list =[x+y for x in l_one for y in l_two]
return new_list

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.

if line not startswith item from a list

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

What is a way to return a list of most common item in a list of lists?

If I had a list such as
[['dog','cat'],['bird','cat'],['dog','squirrel']]
, I am trying to find a way that I would return the most common elements at index [0] of the list among all the sublists and return this as a list.
So if I applied it to the list on top, it'd return:
['dog','bird']
as only those two were at position 0 for their lists and dog was more common.
Like this? You can specify how many you want in most_common.
import collections
animals = [['dog','cat'],['bird','cat'],['dog','squirrel']]
print(list(x[0] for x in collections.Counter(x[0] for x in animals).most_common()))
Use collections.Counter() to count strings and use the Counter.most_common() method to get the most-frequent item:
from collections import Counter
counts = Counter(item[0] for item in yourlist)
print counts.most_common(1)[0][0]
Demo:
>>> from collections import Counter
>>> yourlist = [['dog','cat'],['bird','cat'],['dog','squirrel']]
>>> counts = Counter(item[0] for item in yourlist)
>>> print counts.most_common(1)[0][0]
dog
Is that you mean to have the unique and common elements from the list index 0??
lst = [['dog','cat'],['bird','cat'],['dog','squirrel']];
new_lst = list(set([x[0] for x in lst]))
print new_lst
Output:
['dog', 'bird']

Categories

Resources