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.
Related
I would like to iterate through a list of strings and replace each instance of a character ('1', for example) with a word. I am confused why this would not work.
for x in list_of_strings:
x.replace('1', 'Ace')
Side note, the strings within the lists are multiple characters long. ('1 of Spades)
You can use a list comprehension:
list_of_strings = [x.replace('1', 'Ace') for x in list_of_strings]
This is natural in Python. There is no significant benefit in changing your original list directly; both methods will have O(n) time complexity.
The reason your code does not work is str.replace does not work in place. It returns a copy, as mentioned in the docs. You can iterate over a range object to modify your list:
for i in range(len(list_of_strings)):
list_of_strings[i] = list_of_strings[i].replace('1', 'Ace')
Or use enumerate:
for idx, value in enumerate(list_of_strings):
list_of_strings[idx] = value.replace('1', 'Ace')
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.)
How can I create a new instance of a list or dictionary every time a method is called? The closest thing I can compare what I would like to do is the new keyword in java or C#
These functions are already defined, there are constructors of built in types - dictionary and list:
x = dict()
y = list()
which is an equivalent of Java's
Map x = new TreeMap(); // or other dictionary implementation
List y = new ArrayList(); // or other list implementation
Assuming you have a default list L and you want to make sure you're working with a list equal to L and not mutating L itself, you could initialize a local variable to list(L). Is that what you mean?
Dictionary example:
def create_dict():
return {}
List example:
def create_list():
return []
Usage:
a = create_dict() #for a new empty dictionary
b = create_list() # for new empty list
This all works but is not really that useful as it stands.
The most common way (by far) is:
y= [] # new empty list
x= {} # new empty dictionary
Why so short? Because the language encourages the usage of high-level data structures like these.
In Python, constructors are invoked with the name of the class (like Java), but with no need for new or any other keyword. As mentioned in another answer(s), this makes the following syntax also valid:
x= list()
y= dict()
However, you will rarely find them in practice.
List literals (like [1,2,3,4]) create new lists and pre-populate them. Dictionary literals (like {'Red':'Rojo','Yellow':'Amarillo','Green':'Verde'}) create new dictionaries and pre-populate them too.
Set literals (like {'Morning','Afternoon','Evening','Night'}) are also valid. However, empty sets require to be created as set(). The syntax {} is reserved to create empty dictionaries as they are more common.
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'
How do I remove a character from an element in a list?
Example:
mylist = ['12:01', '12:02']
I want to remove the colon from the time stamps in a file, so I can more easily convert them to a 24hour time. Right now I am trying to loop over the elements in the list and search for the one's containing a colon and doing a substitute.
for num in mylist:
re.sub(':', '', num)
But that doesn't seem to work.
Help!
The list comprehension solution is the most Pythonic one, but, there's an important twist:
mylist[:] = [s.replace(':', '') for s in mylist]
If you assign to mylist, the barename, as in the other answer, rather than to mylist[:], the "whole-list slice", as I recommend, you're really doing something very different than "replacing entries in the list": you're making a new list and just rebinding the barename that you were previously using to refer to the old list.
If that old list is being referred to by multiple names (including entries in containers), this rebinding doesn't affect any of those: for example, if you have a function which takes mylist as an argument, the barename assignment has any effect only locally to the function, and doesn't alter what the caller sees as the list's contents.
Assigning to the whole-list slice, mylist[:] = ..., alters the list object rather than mucking around with switching barenames' bindings -- now that list is truly altered and, no matter how it's referred to, the new value is what's seen. For example, if you have a function which takes mylist as an argument, the whole-list slice assignment alters what the caller sees as the list's contents.
The key thing is knowing exactly what effect you're after -- most commonly you'll want to alter the list object, so, if one has to guess, whole-list slice assignment is usually the best guess to take;-). Performance-wise, it makes no difference either way (except that the barename assignment, if it keeps both old and new list objects around, will take up more memory for whatever lapse of time both objects are still around, of course).
Use a list comprehension to generate a new list:
>>> mylist = ['12:01', '12:02']
>>> mylist = [s.replace(':', '') for s in mylist]
>>> print mylist
['1201', '1202']
The reason that your solution doesn't work is that re.sub returns a new string -- strings are immutable in Python, so re.sub can't modify your existing strings.
for i, num in enumerate(mylist):
mylist[i] = num.replace(':','')
You have to insert the return of re.sub back in the list. Below is for a new list. But you can do that for mylist as well.
mylist = ['12:01', '12:02']
tolist = []
for num in mylist:
a = re.sub(':', '', num)
tolist.append(a)
print tolist
Strings in python are immutable, meaning no function can change the contents of an existing string, only provide a new string. Here's why.
See here for a discussion on string types that can be changed. In practice though, it's better to adjust to the immutability of strings.
Instead of list comprehension, you can also use a map call:
mylist = ['12:01', '12:02']
map(lambda f: f.replace(':', ''), mylist)
Returns:
['1201', '1202']