5

I am new to Python and had a question about updating a list using a for loop. Here is my code:

urls = ['http://www.city-data.com/city/javascript:l("Abbott");' , 'http://www.city-data.com/city/javascript:l("Abernathy");' ,

'http://www.city-data.com/city/Abilene-Texas.html' ,'http://www.city-data.com/city/javascript:l("Abram-Perezville");' ,  

'http://www.city-data.com/city/javascript:l("Ackerly");' , 'http://www.city-data.com/city/javascript:l("Adamsville");', 

'http://www.city-data.com/city/Addison-Texas.html']

for url in urls:
    if "javascript" in url:
        print url
        url = url.replace('javascript:l("','').replace('");','-Texas.html')
        print url

for url in urls:
    if "javascript" in url:
        url = url.replace('javascript:l("','').replace('");','-Texas.html')
print "\n"  
print urls

I used the first for loop to check if the syntax was correct, and it worked fine. But the second for loop is the code I want to use, but it's not working properly. How would I go about globally updating the list with the second for loop so I can print or store the updated list outside of the for loop?

1 Answer 1

7

You can update the list items using their index:

for i, url in enumerate(urls):
    if "javascript" in url:
        urls[i] = url.replace('javascript:l("','').replace('");','-Texas.html')

Another alternative is to use a list comprehension:

def my_replace(s):
    return s.replace('javascript:l("','').replace('");','-Texas.html')

urls[:] = [my_replace(url) if "javascript" in url else url for url in urls]

Here urls[:] means replace all the items of urls list with the new list created by the list comprehension.

The reason why your code didn't worked is that you're assigning the variable url to something else, and changing one of the reference of an object to point to something else doesn't affect the other references. So, your code is equivalent to:

>>> lis = ['aa', 'bb', 'cc']
>>> url = lis[0]                   #create new reference to 'aa'
>>> url = lis[0].replace('a', 'd') #now assign url to a new string that was returned by `lis[0].replace`
>>> url 
'dd'
>>> lis[0]
'aa'

Also note that str.replace always returns a new copy of string, it never changes the original string because strings are immutable in Python. In case lis[0] was a list and you performed any in-place operation on it using .append, .extend etc, then that would have affected the original list as well.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, I found this helpful too. I am newbie and came to SO to do some studying :-) In my study I think I found a slight error in your code. return s.url.replace('javascript:l("','').replace('");','-Texas.html') -- should be -- return s.replace('javascript:l("','').replace('");','-Texas.html')
@Darren Nice catch, fixed that. :-)
is urls[:] needed when replacing with list comprehension? Doesn't it return a new list?
@JimmyKane urls[:] means replace all the items of urls list with the items from iterable on the RHS. This is different than a simple urls = [...]. If he had something like a = b = [1, 2, 3], and then we used b[:] = [x**2 for x in b], then this will affect both a and b.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.