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')
Related
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.
Is there a way of simplifying this loop where i replaces whitespace with dashes for each item in a list?
for item in a_list:
alist[alist.index(item)] = '-'.join(item.split(" "))
or is this better?
for item in a_list:
alist[alist.index(item)] = item.replace(" ", "-")
NOTE: The above solution only updates the 1st occurrence in this list, as David suggested, use list comprehension to do the above task.
I have a list of words and some have dashes while some doesn't. The items in a_list looks like this:
this-item has a-dash
this has dashes
this should-have-more dashes
this foo
doesnt bar
foo
bar
The output should look like this, where all items in list should have dashes instead of whitespace:
this-item-has-a-dash
this-has-dashes
this-should-have-more-dashes
this-foo
doesnt-bar
foo
bar
Use a list comprehension:
a_list = [e.replace(" ", "-") for e in a_list]
When you find yourself using the index method, you've probably done something wrong. (Not always, but often enough that you should think about it.)
In this case, you're iterating a list in order, and you want to know the index of the current element. Looking it up repeatedly is slow (it makes an O(N) algorithm O(N^3))—but, more importantly, it's fragile. For example, if you have two identical items, index will never find the second one.
This is exactly what enumerate was created for. So, do this:
for i, item in enumerate(a_list):
alist[i] = '-'.join(item.split(" "))
Meanwhile, you could replace the loop with a list comprehension:
a_list = ['-'.join(item.split(" ")) for item in a_list]
This could be slower or use more memory (because you're copying the list rather than modifying it in-place), but that almost certainly doesn't matter (it certainly won't be as slow as your original code), and immutable algorithms are simpler and easier to reason about—and more flexible; you can call this version with a tuple, or an arbitrary iterable, not just a list.
As another improvement, do you really need to split and then join, or can you just use replace?
a_list = [item.replace(" ", "-") for item in a_list]
You could use regular expressions instead, which might be better for performance or readability in some similar cases—but I think in this case it would actually be worse. So, once you get here, you're done.
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']