Why isn't my list elements getting casted to int? - python

(I wrote list instead of the actual list names for better understanding)
I'm reading from a file with one number at each line. Then I made it into a list[] and I did list.append(line.replace("\n", "").strip())
When executing the function I wrote - list = inteles(list)
I tried restarting vs code, but it didn't work.

Why not list.append(int(line.replace("\n", "").strip()))

Since when you say for x in y, the x you get isn't able to change the value of the real x in the list. (except with modifying class attributes I believe)
To fix this, just do a list comprehension:
def inteles(lista):
return [int(ele) for ele in lista]

You are not changing the value of the original list, you are not creating a new list either, you are just changing the value of a local variable (to that function). If you want to get a list with all strings converted to a integer, you should create a new list in the function and append the changed local variable to that local list and then return that local list.
Below is a example of that:
foist = [1, 3, "4", "72"]
def inteles(lista):
newlist = []
for sor in lista:
sor = int(sor)
newlist.append(sor)
return(newlist)

Related

accessing values() in collection.Counter as a list

I have this:
lst = [2,2,3,3]
c1 = Counter(lst)
x = c1.values()
I want to know why I get this:
x = dict_values([2, 2])
and what can i do to get this:
x = [2,2]
I want to do this so I can manipulate and compare the data inside, the only way I have found is by doing
x = []
for i in c1.values():
x.append(i)
but I was looking for a more direct way to do this, like
x = c1.values()
I tried looking on the net but I can't find anything
You can turn any iterable (including a dict_values) into a list by passing it to the builtin list constructor:
x = list(c1.values())
Never use builtin names like list or dict as variable names; if you do, like you did here:
list = [2,2,3,3]
you won't be able to use the builtin list any more because you've overwritten its name. You'll need to edit your code to change the name of that variable before trying to use list(c1.values()).
The values returned by calling .values() on a dictionary are wrapped within a dict_values object. You can convert it into a normal list using:
x = list(c1.values())
Or, using your loop logic, but applying it directly to Counter and within a list-comprehension:
x = [v for v in Counter(list).values()]
Also as a general hint I would avoid using the names of python builtins such as list as variable names as that can cause problems and unexpected behaviours.

how this for loop is used in python

Please let me know how this for loop is working.
points = {0,1,2,3,4,8,1}
x = float(sum([len(points) for i in points]))
print(x)
This code snippet is giving me output as:-
36.0
List comprehensions are not that hard if you take a look at a very simple example:
[T(x) for x in X]
The first term is declaring what should be done with all the individual items in the collection we are iterating over. This might be type conversion or just extracting a specific value from a dict.
The symbol after the for just defines the name for our iteration variable and the last term is the collection(list, set, dict etc.) which we iterate through.
A more verbose implementation of the same thing could be:
result = []
for i in range(len(X)):
result.append(T(X[i]))
After this the content of result is the same as the list returned by the list comprehension.

not able to use append function with list in python [duplicate]

I am trying to append objects to the end of a list repeatedly, like so:
list1 = []
n = 3
for i in range(0, n):
list1 = list1.append([i])
But I get an error like: AttributeError: 'NoneType' object has no attribute 'append'. Is this because list1 starts off as an empty list? How do I fix this error?
This question is specifically about how to fix the problem and append to the list correctly. In the original code, the reported error occurs when using a loop because .append returns None the first time. For why None is returned (the underlying design decision), see Why do these list operations return None, rather than the resulting list?.
If you have an IndexError from trying to assign to an index just past the end of a list - that doesn't work; you need the .append method instead. For more information, see Why does this iterative list-growing code give IndexError: list assignment index out of range? How can I repeatedly add elements to a list?.
If you want to append the same value multiple times, see Python: Append item to list N times.
append actually changes the list. Also, it takes an item, not a list. Hence, all you need is
for i in range(n):
list1.append(i)
(By the way, note that you can use range(n), in this case.)
I assume your actual use is more complicated, but you may be able to use a list comprehension, which is more pythonic for this:
list1 = [i for i in range(n)]
Or, in this case, in Python 2.x range(n) in fact creates the list that you want already, although in Python 3.x, you need list(range(n)).
You don't need the assignment operator. append returns None.
append returns None, so at the second iteration you are calling method append of NoneType. Just remove the assignment:
for i in range(0, n):
list1.append([i])
Mikola has the right answer but a little more explanation. It will run the first time, but because append returns None, after the first iteration of the for loop, your assignment will cause list1 to equal None and therefore the error is thrown on the second iteration.
I personally prefer the + operator than append:
for i in range(0, n):
list1 += [[i]]
But this is creating a new list every time, so might not be the best if performance is critical.
Note that you also can use insert in order to put number into the required position within list:
initList = [1,2,3,4,5]
initList.insert(2, 10) # insert(pos, val) => initList = [1,2,10,3,4,5]
And also note that in python you can always get a list length using method len()
Like Mikola said, append() returns a void, so every iteration you're setting list1 to a nonetype because append is returning a nonetype. On the next iteration, list1 is null so you're trying to call the append method of a null. Nulls don't have methods, hence your error.
use my_list.append(...)
and do not use and other list to append as list are mutable.

Python: Using a nested for loop to produce the index for a sublist

I've got the list student:
student = ["test_name","1","6"]
And I've got the read data sublist:
read_data = [["test_name","1","2","5","9"],["test_name_2","1","5","2","10"]]
I've written the following nested loop to return the index of a sublist (referred to as x) in read_data if student[0] == x[0]:
lst = [read_data.index(x) for x in read_data if x[0] == student [0]]
So I'm looping through each item in read data and (if x[0] == student[0]) the index of the sublist should be stored in lst.
When I try to use this in the index parameter of a list to insert data like so:
read_data[read_data.index(x) for x in read_data if x[0] == student[0]].insert(2,student[0])
I get an error saying generators can't be used for indexes - why not?
I can obviously just use the integer stored in lst but this seems inefficient - surely there's a way to do this on one line.
Is there some better alternative method to checking if a string is in any of a read_data's sublists and getting the index of this sublist?
In the assignment to lst you are creating a list. But in the snippet below that, you have merely taken the interior of that list expression and are trying to use it as an index. To fix your specific example, you would need to change:
read_data[iter_expr]
to:
read_data[[iter_expr][0]]
That will use the first value in the list as the index.
There are better ways to do this, but this is probably the smallest change that will fix the specific problem you asked about.
I dont know why you would want to do this but then you need to put brackets around the list comprehension and get index the first match of it like this:
read_data[[read_data.index(x) for x in read_data if x[0] == student[0]][0]].insert(2, student[0])
Remember if the list comprehension produces an empty list, you will encounter an IndexError.

Python: Local variables mysteriously update Global variables

I have a function where I work with a local variable, and then pass back the final variable after the function is complete. I want to keep a record of what this variable was before the function however the global variable is updated along with the local variable. Here is an abbreviated version of my code (its quite long)
def Turn(P,Llocal,T,oflag):
#The function here changes P, Llocal and T then passes those values back
return(P, Llocal, T, oflag)
#Later I call the function
#P and L are defined here, then I copy them to other variables to save
#the initial values
P=Pinitial
L=Linitial
P,L,T,oflag = Turn(P,L,T,oflag)
My problem is that L and Linitial are both updated exactly when Llocal is updated, but I want Linitial to not change. P doesn't change so I'm confused about what is happening here. Help? Thanks!
The whole code for brave people is here: https://docs.google.com/document/d/1e6VJnZgVqlYGgYb6X0cCIF-7-npShM7RXL9nXd_pT-o/edit
The problem is that P and L are names that are bound to objects, not values themselves. When you pass them as parameters to a function, you're actually passing a copy of the binding to P and L. That means that, if P and L are mutable objects, any changes made to them will be visible outside of the function call.
You can use the copy module to save a copy of the value of a name.
Lists are mutable. If you pass a list to a function and that function modifies the list, then you will be able to see the modifications from any other names bound to the same list.
To fix the problem try changing this line:
L = Linitial
to this:
L = Linitial[:]
This slice makes a shallow copy of the list. If you add or remove items from the list stored in L it will not change the list Lintial.
If you want to make a deep copy, use copy.deepcopy.
The same thing does not happen with P because it is an integer. Integers are immutable.
In Python, a variable is just a reference to an object or value in the memory. For example, when you have a list x:
x = [1, 2, 3]
So, when you assign x to another variable, let's call it y, you are just creating a new reference (y) to the object referenced by x (the [1, 2, 3] list).
y = x
When you update x, you are actually updating the object pointed by x, i.e. the list [1, 2, 3]. As y references the same value, it appears to be updated too.
Keep in mind, variables are just references to objects.
If you really want to copy a list, you shoud do:
new_list = old_list[:]
Here's a nice explanation: http://henry.precheur.org/python/copy_list

Categories