Modifying local variable with same name effect also global

Question:

I’m new in python and using bs4, I try to change attribute name for some list of tags to use this list on different place with different attributes but with same text value

I have this global variable: x = soup.find_all(attrs={"name": "some_name"})

x global variable provide me with list so I can use it in some org_tag.contents = x

In some other new tag.contents = ylist() I want to use function with list with same text values as x have but with different attributes names.

I have this code to do that:

# test.py

x = soup.find_all(attrs={"name": "some_name"})

### x = find this list:
###  <column name="some_name">
###   my text value
###  </column>
###   <column name="some_name">
###   my text value
###  </column>
###
 
def ylist():
    for i in range(len(x)):
        x[i]['name'] = "some_other_name"
    return (x)

# first original tag

org_tag = soup.new_tag("table")
org_tag.name = "table"
org_tag['name'] = "some_table"
org_tag.contents = x
soup.append(org_tag)

# new tag
newtag = soup.new_tag("table")
newtag.name = "table"
newtag['name'] = "some_other_table"
newtag.contents = ylist()
soup.append(newtag)

What happens is that my function ylist() change all global variables to new attribute name, but I want new attribute name only local at new_tag

My understanding is that in python global variables changes only if I use – global x – inside of function.

So my question why my function changes all global variables and how to get only new attribute name only local at new_tag

Edit:
Here is solution as is suggested from second answer

## use of deepcopy
def ylist():
    a = copy.deepcopy(x)
    for i in range(len(a)):
        a[i]['name'] = "some_other_name"
    return (a) 

Thank you

Asked By: Darko

||

Answers:

Because your function is no properly constructed.

def ylist(x):
    x_content = x.copy
    for i in range(len(x)):
        x_content[i]['name'] = "some_other_name":
    return x_content

Now you can fix this part of your code as well:

Change:

newtag.contents = ylist()
soup.append(newtag)

To

my_newtag = ylist(newtag.contents)
soup.append(my_newtag)
Answered By: Jamiu Shaibu

if I understand your question correctly, you could use the copy method of list object to create a new object with the same data as the initial list variable.

def ylist():
    x_copy = x.copy()
    for i in range(len(x_copy)):
        x_copy[i]['name'] = "some_other_name"
    return x_copy

also, you can check the copy module for advanced use of copy objects. you can find more about copying list objects in this link.

Answered By: AmirMohammad Babaei
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.