Generally, a list comprehension follows a following pattern:
my_list = [record for record in records_set]
It could be extended to, for example, the following expression, if record is a dictionary:
my_list = [(record['attribute_a'],record['attribute_b']) for record in records_set]
What if I want the list comprehension to take a list of attributes I want to extract from a record as an argument?
Lets say I have a list
attributes_list = ['attribute_a','attribute_b','attribute_c']
As a result of applying it to the list comprehension pattern, I want to get the following list comprehension as a result:
my_list = [(record['attribute_a'],record['attribute_b'],record['attribute_c']) for record in records_set]
How do I do it?
You can do:
my_list = [tuple(record[attr] for attr in attributes_list) for record in records_set]
The easiest thing to do is use operator.itemgetter
from operator import itemgetter
values_from = itemgetter(*attributes_list)
my_list = [values_from(record) for record in record_set]
This makes it easy to skip the list comprehension and use map instead.
my_list = list(map(itemgetter(*attributes_list), record_set))
(As usual, the call to list is necessary in Python 3, not Python 2.)
Related
I want to write a list comprehension that will have print an element out of an array every other element. How do I do so?
for item in results:
record = extract_record(item)
if record:
records.append(record)
in Python 3.8 or later you could make use of the assignment expression and do something like
records = [record for item in results if (record := extract_record(item))]
This avoids having to extract the record twice.
The list comprehension equivalent of the above will be:
records = [extract_record(item) for item in results if extract_record(item)]
Note that extract_record() is needed twice and hence not so useful.
I'm trying to slice a list in a certain way in Python. If I have a list that looks like this:
myList = ['hello.how.are.you', 'hello.how.are.they', 'hello.how.are.we']
Is there a way to slice it so that I can get everything after the last period for each element? So, I would want "you", "they", and "we".
There's no way to slice the list directly that way; what you do is slice each element.
You can easily build a list comprehension where you split on the period and take the last element.
myList = ["hello.how.are.you", "hello.how.are.they", "hello.how.are.we"]
after_last_period = [s.split('.')[-1] for s in myList]
Yes, it can be done:
# Input data
myList = ["hello.how.are.you", "hello.how.are.they", "hello.how.are.we"]
# Define a function to operate on a string
def get_last_part(s):
return s.split(".")[-1]
# Use a list comprehension to apply the function to each item
answer = [get_last_part(s) for s in myList]
# Sample output
>>> answer: ["you", "they", "we"]
A footnote for speed demons: Using s.rpsilt(".", 1)[-1] is even faster than split().
[i.split('.')[-1] for i in myList]
Assuming that you omitted quotes around each list element, use a list comprehension and str.split():
[x.split('.')[-1] for x in myList]
I have a function which returns strings. What I would like to do is get these strings and save it into a list. How can I do this?
for i in objects:
string = getstring(i)
x = 0
list[x] = string
x = x+1
You should first declare the list:
L = []
then, in the for loop, you can append items to it:
for i in objects:
string = getstring(i)
L.append(string)
It is better to use a list comprehension in this case,
my_list = [getstring(obj) for obj in objects]
Instead of creating a list and storing string in it, we are creating a list of strings, based on the objects in objects. You can do the same with map function as well
my_list = map(getstring, objects)
This takes each and every item in objects and applies getstring function to them. All the results are gathered in a list. If you are using Python 3.x, then you might want to do
my_list = list(map(getstring, objects))
Since using map is not preferred, whenever possible go with List Comprehension. Quoting from the BDFL's blog,
Curiously, the map, filter, and reduce functions that originally motivated the introduction of lambda and other functional features have to a large extent been superseded by list comprehensions and generator expressions.
Up until now I have been using this code to uniquify (remove duplicates) from list in python:
my_list = list(set(my_list))
I now have a list of lists, I want to be able to remove duplicates from within the list of lists. For example:
(['possible-duplicate', 'random-data'], ['possible-duplicate', 'random-data'], ['possible-duplicate', 'random-data'])
I want to remove the whole sublist if possible-duplicate is a duplicate.
Can this be done?
Thanks
seen = set()
[sublist for sublist in my_list if sublist[0] not in seen and not seen.add(sublist[0])]
This happens to preserve order as well, which list(set(...)) does not.
Make a dictionary from your data:
data = (['possible-duplicate', '12345'],
['not-a-duplicate', '54321'],
['possible-duplicate', '51423'])
data_unique = dict(data)
Result is {'not-a-duplicate': '54321', 'possible-duplicate': '51423'}, or if you prefer a list of tuples, use date_unique.items(), which gives you [('not-a-duplicate', '54321'), ('possible-duplicate', '51423')].
Or for the more general case, where the sublists have more than two elements, you can use this
data_unique = dict((d[0], d) for d in data)
and then use data_unique.values() to reclaim the "uniquified" list.
how would you turn this string:
str='ldap:alberthwang,eeid:67739|ldap:meng,eeid:107,building:CL5'
into a list that give you this:
print x[1]['building']=CL5
which would be:
x=[{'ldap':'alberthwang','eeid':'67739'},{'ldap':'meng','eeid':'107','building':'CL5'}]
i've tried to split the string first and append to a list:
sample=[]
for s in str.split('|'):
sample.append(s)
But i'm stuck on how to turn the list items into a dictionary that i can then use to populate another list.
text='ldap:alberthwang,eeid:67739|ldap:meng,eeid:107,building:CL5'
sample=[
dict(item.split(':') for item in part.split(','))
for part in text.split('|')]
print(sample)
# [{'eeid': '67739', 'ldap': 'alberthwang'}, {'building': 'CL5', 'eeid': '107', 'ldap': 'meng'}]
print(sample[1]['building'])
# CL5
List comprehensions are a very convenient way to construct
lists such as this.
A dict can be constructed from an iterable of key-value pairs. The iterable used above was a generator expression.
str is a built-in type, so assigning a string to str overwrites
the builtin. It's better to choose some other variable name to avoid
future surprising bugs.
I read and write list comprehensions backwards:
[ expression # (3)
for variable in # (2)
iterable # (1)
]
(1): First, understand the iterable. In the solution above, this is text.split('|').
(2): for variable in causes variable to be assigned to the values in iterable, one at a time.
(3): Finally, expression can be any Python expression, (usually) using variable.
The syntax for generator expressions is almost the same. The difference between a list comprehension and a generator expression is that a list comprehension returns a list, while a generator expression returns an iterator -- an object that yields its contents on-demand (as it is looped over, or when next is called) instead of generating all the items at once as is the case with lists.
A list can consume a lot of memory if the list is long.
A generator expression will consume less memory (and can even be infinite) because not all elements have to exist in memory at the same time.
Using str as a variable name is a bad idea, since it overshadows the built-in str.
s ='ldap:alberthwang,eeid:67739|ldap:meng,eeid:107,building:CL5'
res = [dict(colonStr.split(':') for colonStr in ds.split(','))
for ds in s.split('|')]
stores the result you what in res.
The key insight here is that dict can take a list of key/value pairs. So, you can do this using a comprehension like this:
string = 'ldap:alberthwang,eeid:67739|ldap:meng,eeid:107,building:CL5'
list_of_dicts = [dict(item.split(':') for item in items.split(',')) for items in string.split('|')]
print list_of_dicts
Maybe this way:
>>> s = 'ldap:alberthwang,eeid:67739|ldap:meng,eeid:107,building:CL5'
>>> x = [dict([d.split(':') for d in ls.split(',')]) for ls in s.split('|')]
>>> x[1]['building']
>>> 'CL5'