List append method within a function not working - python

I have a table of data in a txt file.
I bring it into Python with:
a1_file=open(file_path,'r')
then I go to the second line to skip the headers:
a1_file.readline()
line_string=a1_file.readline()
Being a comma separated function I want to obtain a list where the position of the first 5 commas is stored. To this purspose I am trying to use this function:
def commas_in_line(table_row):
commas=[]
while len(commas) <5:
if len(commas)==0:
i=0
else:
i=commas[-1]+1
k=table_row.find(',',i)
commas=commas.append(k)
return commas
I call the function with:
commas_in_line(line_string)
The code reports this error:
Traceback (most recent call last):
File "<pyshell#52>", line 1, in <module>
commas_in_line(line_string)
File "C:/1WritingPrograms.py", line 11, in commas_in_line
while len(commas) <5:
TypeError: object of type 'NoneType' has no len()
with
>>> line_string
'30/04/2020,30,4,2020,122,0,Afghanistan,AF,AFG,37172386,Asia\n'
I tried substituting in the function:
commas=commas.append(k)
with:
commas=commas+[k]
and it works, but how can I use the append method? Why does it fail?

Essentially .append() does not return the new array. .append() is sort of like an inplace function, where the value is appended into the array. So you do not have to return anything. When you say commas=commas.append(k), a new entity is returned, which is NoneType. Please just leave it as commas.append(k)

You add values to a python list with:
commas.append(k)
You use the = operator to define a list, not to alter one. For instance, for
commas = ['a', 'b', 'c']
commas.append('d')
commas will now be (a, b, c, d).
There is more about python lists here https://www.w3schools.com/python/python_lists.asp

Related

Python interprets list as a tuple by mistake

I have this piece of code:
for keys in self.keys:
if has_classes := self.class_checker(keys[0]):
print(type(keys[0])) -> #just for demonstrating that it is actual list
keys[0] = [x for x in keys[0] if 'class="' not in x]
for classes in has_classes:
keys[0].append(f'class="{classes}"')
I want to change the list by using list comprehension and it is showing this error:
<class 'list'>
Traceback (most recent call last):
File "C:\Users\USER\OneDrive\Desktop\XPATH\base\main.py", line 300, in <module>
XPanther('<h1 class="Uo8X3b OhScic zsYMMe">Lidhjet e qasshmërisë</h1>', 'C:\\Users\\USER\\OneDrive\\Desktop\\XPATH\\xpath_test_case.txt').capture()
File "C:\Users\USER\OneDrive\Desktop\XPATH\base\main.py", line 100, in capture
keys[0] = [x for x in keys[0] if 'class="' not in x]
~~~~^^^
TypeError: 'tuple' object does not support item assignment
As you can see on the first line of the error, it is printing the type of keys[0] as a list (which I also know is a list but anyways), and then it suddenly becomes a tuple ?
I'm very confused, please someone help me!
As #bereal has mentioned (and others..) in the comments of my post, the actual case for this problem is that I tried to change the contents of a list,which that list happens to be inside a tuple, which is immutable in itself, so i can't change it's values at all. The obvious solution would be to first transform the tuple into a list,then back again as a tuple if you want.

TypeError: 'bool' object is not iterable eventhough using another variable

First post ever :)
I know that the if statement returns a Boolean value. But I am not using it to iterate a list, I'm using x. I just want all other variables (type = IntVar) to be set to 0 except for i which has to remain 1. Thanks in advance, my first ever time here...
def clear():
variables=[var, var0, var1, var2, var3, var4,var5,var6, var7, var8]
for i in variables:
if i.get() == 1:
x = variables.index(i)
for y in variables in range(0,x-1) and range(x,9):
y.set(0)
My original code is 500 lines long so not ideal to post it full here.
Full traceback:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Thomas Jence\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
File "G:\Mrs. Odewale\Computing coursework\options.py", line 187, in clear9
for y in variables in range(0,x-1) and range(x,9):
TypeError: 'bool' object is not iterable
for y in variables in range(0,x-1) and range(x,9):
is interpreted as (split up with parentheses and by line to make groupings clear):
for y in (
variables in (
range(0, x-1) and range(x,9)
)
):
The innermost parentheses then determine if range(0, x-1) is empty or not, and use it if it's not, and use range(x,9) if it is. The next layer then tests if variables is in the "winning" range. Then you effectively do:
for y in False:
because variables is a list, so it's definitely not in any range.
I don't know what you're trying to do, but you need to reconsider that line.
Not familiar with python, but as a standard coding practice you never want to change values in an array while you are iterating through them.
Instead create a new array, which has same values as the existing array. iterate the old array while setting values of the new array, and then after the loop, set the your array to the new values of the new array.

Why do i get the TypeError "argument of type 'type' is not iterable"?

I am trying to add some keys to my dictionary after testing if they are already existing keys. But I seem not to be able to do the test, every time I get the TypeError "argument of type 'type' not iterable.
This is basically my code:
dictionary = dict
sentence = "What the heck"
for word in sentence:
if not word in dictionary:
dictionary.update({word:1})
I also tried if not dictionary.has_key(word) but it didn't work either so I am really confused.
Your error is here:
dictionary = dict
That creates a reference to the type object dict, not an empty dictionary. That type object is indeed not iterable:
>>> 'foo' in dict
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argument of type 'type' is not iterable
Use {} instead:
dictionary = {}
You could also have used dict() (calling the type to produce an empty dictionary), but the {} syntax is preferred (it is faster and easier to scan for visually in a piece of code).
You also have an issue with your for loop; looping over as string gives you the individual letters, not words:
>>> for word in "the quick":
... print(word)
...
t
h
e
q
u
i
c
k
If you wanted words, you could split on whitespace with str.split():
for word in sentence.split():

Can you assign object instances directly to a list in Python?

I've defined a class called Space, meant to represent spaces on a 9x9 board. I want to generate 81 instances at the beginning of the program by assigning them to elements of a list that I intend to use as a 2D array.
Here's the class:
class Space:
def __init__(self, x_coord, y_coord):
self.row = x_coord
self.column = y_coord
Here's one of my attempts to assign instances to a list (also called space):
for i in xrange(1,9):
for j in xrange(1,9):
space[i][j] = Space(i,j)
My goal here is to be able to reference instances using the list indices as if they were coordinates, ie space[1][2].value = 3
Is what I'm trying to do possible? Is there a better way to generate instances en masse? Thanks!
Edit: (My response below in more readable form)
The script runs, but it looks like my list is not defined when I try to access it in the command prompt
>>> space[1][2].value = 3
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
NameError: name 'space' is not defined
>>> space[1][1]
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
NameError: name 'space' is not defined
It sounds like you're never creating the space lists you're trying to use to hold your Space objects. Here's one way to do it, by starting with an empty list and appending the values into the list as you go:
space = [] # initially empty list
for i in range(9):
column = [] # create an empty list to hold a column of values
for j in range(9):
column.append(Space(i, j)) # add the object to the column
space.append(column) # add the column to the outer list
A cleaner, more "Pythonic" solution is to use nested list comprehensions, as in isedev's answer:
space = [[Space(i, j) for j in range(9)] for i in range(9)]
As a final note, using the same word with only capitalization differences for different things in your code is probably a bad idea. It can be OK to use a variable named foo to hold a single Foo instance, but a better name would indicate what the instance is for, e.g. foo_for_frobbing. In your case, board might be a better name than space for your list of Space instances.
You'll have to use 0-based indexing, but this will achieve what you want:
space = [[Space(i,j) for j in range(9)] for i in range(9)]

Is there a more Pythonic way to pad a string to a variable length using string.format?

I want to pad a string to a certain length, depending on the value of a variable, and I'm wondering if there is a standard, Pythonic way to do this using the string.format mini-language. Right now, I can use string concatenation:
padded_length = 5
print(("\n{:-<" + str((padded_length)) + "}").format("abc"))
# Outputs "abc--"
padded_length = 10
print(("\n{:-<" + str((padded_length)) + "}").format("abc"))
#Outputs "abc-------"
I tried this method:
print(("{:-<{{padded_length}}}".format(padded_length = 10)).format("abc"))
but it raises an IndexError: tuple index out of range exception:
Traceback (most recent call last):
File "<pyshell#41>", line 1, in <module>
print(("{:-<{{padded_length}}}".format(padded_length = 10)).format("abc"))
IndexError: tuple index out of range
Is there a standard, in-built way to do this apart from string concatenation? The second method should work, so I'm not sure why it fails.
print(("\n{:-<{}}").format("abc", padded_length))
The other way you were trying, should be written this way
print(("{{:-<{padded_length}}}".format(padded_length=10)).format("abc"))
The following example should provide a solution for you.
padded_length = 5
print("abc".rjust(padded_length, "-"))
prints:
--abc
You need to escape the outer most curly brackets. The following works fine for me:
>>>'{{0:-<{padded_length}}}'.format(padded_length=10).format('abc')
'abc-------'

Categories

Resources