python logic setting variable to none - python

Ive done enough research to understand my logic (I believe):
I have python code to set a variable to None so that at the db level it stores the value of this variable to Null.
Logic looks like:
# when properly set to something other than `None` an example value might be: ['6.1 ', 'Medium'
thesev=cve.find("span", class_="label-warning").text
thesevcat=re.split("- ", str(thesev))
if thesevcat is None:
thesevcat=None
else:
#looking to set thesevcat='Medium' for example
thesevcat=thesevcat[1]
sometimes thesevcat is successfully parsed the value, othertimes it cant parse it, so I want to set it to None
However, I keep getting this error:
thesevcat=thesevcat[1]
IndexError: list index out of range
what is going wrong here? Thanks

thesevcat=thesevcat[1]
IndexError: list index out of range
List index out of range is pretty explicit, it means that if thesevcat is in fact a list (which we don't really know seeing your code but I guess it is), it doesn't have a 2nd index, which means it's a list containing in maximum one element (for instance ["medium"] )
Please keep in mind that the first index of a list is 0, so if your list is your_list = ["medium"], to access "medium", you need to write your_list[0]
if you wanted to access the 2nd element of your list, then your list would need to be at least 2 element long, then you'd access it with the index 1
for instance:
your_list = ["medium", "large"]
print(your_list[1])
# would print large

Related

Looping for loop in Python

I have the following code.
for idx in range(len(networks)):
net_ = networks[idx]
lastId=0
for layerUptID in range(len(net_[1])):
retNet,lastId=cn_.UpdateTwoConvLayers(deepcopy(net_),lastId)
networks.append(retNet)
if(lastId==-1):
break
networks has only one net at the beginning.
After running the line retNet,lastId=cn_.UpdateTwoConvLayers(deepcopy(net_),lastId), I have additional six nets and appended to networks.
So after this lastId ==-1, go back to first for loop with len(networks) is 7.
For the next idx, idx=1 and continue.
Then, len(networks) is 13. Then go back to first for loop.
After this, the first for loop breaks.
I am expecting to continue for idx is 2, but it breaks.
What could be the issue?
If you try using a WHILE loop instead of FOR loop, the break statement would be check if the loop is on the last item in 'networks' collection.
This way the network length would be calculated in each loop iteration
For starters: Iterating, or looping, over the list (or data) you're editing is bad practice. Keep that in mind while coding.
This means if you plan to edit what you're looping on, in your case networks, then you're going to have a bad time looping over it. I would advise to break it up into two code parts:
The first part creates a new list of whatever it is you want WHILE looping.
The second part replaces the list you've used to generate what you wanted.
Another thing which could go wrong is net_[i] may not be set up for some i, and you're trying to access it here:
for layerUptID in range(len(net_[1])):
What if there is nothing in net_[1]?
To avoid these errors, usually verifying your data is a great way to start. If it is not null, then proceed, otherwise, print an error.
This is what I can think of. Hope it helps.
If I understood correctly your problem is that you've added new elements to networks, i.e. have increased length of networks and expect that for-loop will pick up this changes, well it's not, let's look at following snippet
elements = [1]
indices = range(len(elements))
for index in indices:
print('index is', index)
elements.append(2)
print('elements count is', len(elements))
print('indices count is', len(indices))
outputs are
index is 0
elements count is 2
indices count is 1
so as we can see despite the fact that length of elements list has changed, range object which is used in for-loop has not. This happens because len returns int object which are immutable, so when you change list length its length becomes different object and range function has no idea about this changes.
Finally, we can use while loop here like
while networks:
net_ = networks.pop()
lastId = 0
for layerUptID in range(len(net_[1])):
retNet, lastId = cn_.UpdateTwoConvLayers(deepcopy(net_), lastId)
networks.append(retNet)
if lastId == -1:
break

Python list - string formatting as list indices

Depending on a condition I need to get a value from one or another function. I'm trying to put it inside a simple If ... Else statement. I tried to use %s string formatting but it won't work. Below code, so it will become more clear what I try to do:
if condition:
item = my_list['%s']
else:
item = my_other_list['%s']
# now I do something with this value:
print item % 3
This way I tried to print 3rd value of one or other list if the condition was True of False. This returned an error about list indices being string. So I tried to put it inside int() what didn't help.
How should I do it? The problem is I get the value later than I declare what item is.
EDIT
I will add some more infos here:
I have a for loop, that goes through ~1000 elements and processes them. If the condition is True, it calls one function or another if false. Now, I don't want to check the same condition 1000 times, because I know it won't change during the time and would like to check it once and apply the method to all of the elements.
More code:
if self.dlg.comboBox_3.currentIndex == 0:
item = QCustomTableWidgetItem(str(round((sum(values['%s'])/len(values['%s'])),2)))
else:
item = QCustomTableWidgetItem(str(round(sum(values['%s'],2))))
for row in range(len(groups)):
group = QTableWidgetItem(str(groups[row]))
qTable.setItem(row,0,group)
qTable.setItem(row,1,item % row)
This is the actual code. Not the '%s' and '% row'. I used simplified before not to distract from the actual problem, but I think it's needed. I'm sorry if it wasn't a good decision.
You have a reasonably large misconception about how list slicing works. It will always happen at the time you call it, so inside your if loop itself Python will be trying to slice either of the lists by the literal string "%s", which can't possibly work.
There is no need to do this. You can just assign the list as the output from the if statement, and then slice that directly:
if condition:
list_to_slice = my_list
else:
list_to_slice = my_other_list
# now I do something with this value:
print list_to_slice[3]
Short answer:
'%s' is a string by definition, while a list index should be an integer by definition.
Use int(string) if you are sure the string can be an integer (if not, it will raise a ValueError)
A list is made up of multiple data values that are referenced by an indice.
So if i defined my list like so :
my_list = [apples, orange, peaches]
If I want to reference something in the list I do it like this
print(my_list[0])
The expected output for this line of code would be "apples".
To actually add something new to a list you need to use an inbuilt method of the list object, which looks something like this :
my_list.append("foo")
The new list would then look like this
[apples, orange, peaches, foo]
I hope this helps.
I'd suggest wrapping around a function like this:
def get_item(index, list1, list2)
if condition:
return list1[index]
else:
return list2[index]
print get_item(3)
Here is a compact way to do it:
source = my_list if condition else my_other_list
print(source[2])
This binds a variable source to either my_list or my_other_list depending on the condition. Then the 3rd element of the selected list is accessed using an integer index. This method has the advantage that source is still bound to the list should you need to access other elements in the list.
Another way, similar to yours, is to get the element directly:
index = 2
if condition:
item = my_list[index]
else:
item = my_other_list[index]
print(item)

Pythonic way to get last index value of enumerate

When I enumerate through a list, is there an intended, pythonic way of obtaining the last index value provided?
Something that would get the equivalent of this:
highest = None
for index, value in enumerate(long_list):
# do stuff with index and value
highest = index
return highest
This approach I don't like. It has hundreds of unnecessary variable assignments. Also, it's ugly.
Background: I have an ordered list build with a RDBS and SQLAlchemy, using numbers as indexes in the relation table. Also I store the highest used index number in the list table, for easy appending of new entries (without extra max lookup on relation table). For when things get messed up, for whatever reason, I included a reorg function, that rebuilds indexes starting from 0 (to remove any gaps). I to that by for-enumerate-iterating over the association table. After that I need to count them or max the index, to get my new highest index value for the list table. That kinda bugs me.
Suggestions? Preferably something that works in 2.7.
To get the last index of a list
len(mylist)-1
To get the last element of a list you can simply use a negative index.
mylist[-1]

Finding a maximum in a defined part of a list

Being a beginner, I am not sure that I am formulating the question correctly, but here is my problem:
I am trying to define a function where, given a list, a beginning and an end, the program would return the maximum of that list between the postions 'beginning' and 'end'. Here is my code:
def eleMax(liste, debut=0, fin=99999999):
if fin > len(liste):
fin=len(liste)
for i in liste:
while i in range(liste[debut], liste[fin]):
return max(i)
However there seems to be several problems. Here, I get: 'list index out of range'. In other versions of this code I also kept getting 'int object is not iterable', which I think is linked to debut and fin being arguments.
Is this approach even possible? Or should I try a whole different method?
You are returning the maximum of one single value.
You need to instead slice the list:
def eleMax(liste, debut=None, fin=None):
return max(liste[debug:fin])
There is no need to constrain the end value to the length of the list. You can leave debut and fin set to None instead, to fall back to the Python defaults (which are 0 and the length of liste, respectively).

How to use the index of a min value on one list to find the position of a string on another list

I am currently trying write a function to use the position of a min value on one list to reference a string on another list.
I have two list, one with states names and another with floats. I am using the min method to get the minimum value of the float list. The problem is, how I use an index to mark the position of that value then use it to return the state that holds the same position on the other list?
This is the code I am currently using, but it does not go all the way through the list before it returns a value, which is way too soon in the list.
def stateheart_min():
for item in heartdis_flt:
heartcount=0
heartcount+=1
min_index=0
if item == min(heartdis_flt):
min_index=heartcount
return states_fin[min_index:min_index+1]
This is a bit terse to read, but here is an alternative way to do it. You can use min to find the minimum value in values. Then you can use index to find the index at which the minimum occurs in the list. You can then use that returned index to index the correct element from states.
states = ['NY', 'PA', 'CA', 'MI']
values = [15.0, 17.5, 3.5, 25.4]
>>> states[values.index(min(values))]
'CA'
Try this:
index = min(zip(values, range(len(values))))[1]
This first builds a list of pairs, each having a value as first item and its index as second item. So when you find the minimum, the first item still has the main impact (the index will only be taken into account if the values are equal). Taking the index is then done using [1] in the end.
Not entirely sure what you are asking, but a dictionary might be a better choice. Also setting heartcount=0 inside the loop resets the variable back to 0 each iteration. Check your variables inside the loop.

Categories

Resources