index error while running a loop over list contents - python

I have a list like this:
my_array= ["*","device",":","xyz"], ["+","asd","=","10","pdf","=","6"],
["+","dsa","=","1","pqa","=","2","dga","=","12"], ["*"]
What I want to do is:
define('device','xyz')
define('asd','10')
define('pdf','6')
define('dsa','1')
define('pqa','2')
define('dga','12')
The way I approached is:
i=0
while i < len(my_array):
if my_array[i][0]=="*":
print("'",my_array[i][1],"'","'",my_array[i][3:],"'")
elif my_array[i][0]=="+":
print("'",my_array[i][1],"'","'",my_array[i][3],"'")
if my_array[i][4]=="\D":
print("'",my_array[i][4],"'","'",my_array[i][6],"'")
elif my_array[i][7]=="\D":
print("'",my_array[i][7],"'","'",my_array[i][9],"'")
i=i+1
But doing this, I get index error. I know where the problem is, but I cannot fix it with my very bad programming brain. Can someone help me on this?

First review problem seems in
if my_array[i][0]=="*":
print("'",my_array[i][1],"'","'",my_array[i][3:],"'")
because last element in your my_array is ['*'] and it has no other elements and u are trying to access my_array['*'][1] and its give index error.
You have to remove that element or add members who fulfill element index requirement.

Hard-coding the indices is a sure sign you're doing something wrong - the items in my_array have variable lengths, so some of your indices inevitably fail. I think what you want is something like:
for command in my_array:
if command[0] in ("*", "+"):
for start in range(1, len(command), 3):
assignment = command[start:start+3]
if assignment[1] in ("=", ":"):
print assignment[0], assignment[2]
It is worth noting, however, that you seem to be attempting to write a file parser. Although this code solves this specific problem, it is likely that your overall approach could be improved.

With the assumption, that every key in your list has a value attached to it(e.g. there are no two asterisk following after each other) you can make some simplifications:
We'll read the first value as a key of a new dict and the second item as the value.
With the newly tidied up dict(d) you can continue to work easily e.g. in a for loop:
array=["*","device",":","xyz"], ["+","asd","=","10","pdf","=","6"],
["+","dsa","=","1","pqa","=","2","dga","=","12"], ["*"]
d = {}
for list in array:
new_key = None
for item in list:
if item in ['*',':','+','=']: continue
if new_key == None:
new_key = item
else:
d[new_key] = item
new_key = None
for key in d:
define(key,d[key])

Related

How to use the index in an enumerate for loop with if statement (python)

I have a nested dictionary, of which it is possible to access a value like this:
print(list['sublist'][0]['item'][0]['commentId'])
However if I create a for loop and would like to use the index like this it gives me a keyerror:
for index,sublist in enumerate(list['sublist']):
if sublist[index]['item'][0]['commentId'] == commentid:
number = sublist[index]['item'][0]['positionId']
username = sublist[index]['subListCreator']
print(number)
print(username)
The error:
, in send_async_notification
if sublist[index]['item'][0]['commentId'] == commentid:
File "/Users/ ...... /venv/lib/python3.8/site-packages/mongoengine/base/document.py", line 263, in __getitem__
raise KeyError(name)
The whole goal of this exercise is to get two particular values in a nested array based on a deeper nested commentId. If there is a match, I would like to know the positionId and the subListCreator underneath it. An item can only have one commentId, hence the [0] in the code.
It would also be ok to just have the whole dictionary "branch" that matches the commentId, this would also make things work.
Btw, print(commentid) gives me the commentid I would like to match against. Just to explain its present.
Hope there's a solution here, wonder why it's not working. Looking forward to any answer!
Thanks Mathias for commenting! A double for-loop solves my problem:
for sublist in list['sublist']:
for item in sublist['item']:
if item['commentId'] == commentid:
number = item['positionId']
username = sublist['subListCreator']

How do I merge dictionaries having similar values in Python?

I have a problem.
Input=[
{'id':uuid1(),'name':'mem','point':[{'second':0,'severity':'infor'}],'date':'2021-09-15','PO':5},
{'id':uuid1(),'name':'cpu','point':[{'second':10,'severity':'warning'}],'date':'2021-09-13','PO':3},
{'id':uuid1(),'name':'cpu','point':[{'second':20,'severity':'critical'}],'date':'2021-09-14','PO':3},
{'id':uuid1(),'name':'cpu','point':[{'second':30,'severity':'infor'}],'date':'2021-09-15','PO':3}]
I will compare in this array. If the same name, I will combine all value of this dict.
It mean combine all value of key 'point'. I will have key list 'point' with multi dict
We have many duplicate key name = 'cpu'. So I will combine all value if the same value.U see we have PO the same value (PO=3 with name=cpu).If different value, we will take the last value(last value 'date':'2021-09-15').Finally, we will append the dicts in the key point list together
Desired result
Output=[
{'id':uuid1(),'name':'mem','point':[{'second':0,'severity':'infor'}],'date':'2021-09-15','PO':5},
{'id':uuid1(),'name':'cpu','point':[{'second':10,'severity':'warning'},
{'second':20,'severity':'critical'},
{'second':30,'severity':'infor'}],'date':'2021-09-15','PO':3}
]
Note: I use python 3.6
I hope someone will help me. Thank you very muck
There is probably a better way to do this but the following works:
a=[{'name':'mem','point':[{'second':0,'severity':'infor'}],'date':'2021-09-15','PO':5},
{'name':'cpu','point':[{'second':10,'severity':'warning'}],'date':'2021-09-13','PO':3},
{'name':'cpu','point':[{'second':20,'severity':'critical'}],'date':'2021-09-14','PO':3},
{'name':'cpu','point':[{'second':30,'severity':'infor'}],'date':'2021-09-15','PO':3}]
b=[]
for i in a:
for j in b:
if i['name'] == j['name']:
j['point'] += i['point']
break
else:
b.append(i)

Python3: for-loop break and else (if statement)

Background information:
hey,
I want to do the following: I have a dictionary with IDs as keys and lists with various things as value. One of the items of the value is a string. I want to check, if a list contains this string. And I want to do it for all keys in my dictionary.
If the list contains the string, I want to print "String is valid"
If the list does not contain the string, I want to print "String is NOT valid"
So far, so good.
Furthermore, the lists I want to check depend on one console input of the user, which specifies, which list should be checked. The console input is "number".
My idea was to iterate over my dictionary and my list with a nested for-loop and compare, if the string(the item of the value) is equal to any list item. If it is, I want to break out of the loop. If the String is not found in the list, I want to execute the else-statement to print my "String is not valid" message.
Code snippet:
def validationHelper(myDict, myList):
for key in myDict:
for value in myDict[key][0]:
for item in myList:
if value==item:
validationHelper.true="String is valid"
break
else:
validationHelper.true="Warning: String is NOT valid"
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
if anyList=="two":
return helperfunc(finalDict,myList2)
if anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper.true)
Problem:
I am running this, but no matter if the string is in the list or not, I always get my printout for the else-statement. So, I guess I have an error in reasoning in my for-loop? Or maybe, I did not understand for-loops at all?! I have tried out different indentions with the else-statement, but couldnt solve my problem.
I would suggest you to change your function the following way (without changing the logic):
def validationHelper(myDict, myList):
for key in myDict:
for value in myDict[key][0]:
for item in myList:
if value==item:
return "String is valid" # Add here to exit
return "Warning: String is NOT valid" # will be returned inf nothing will be found in your 3 loops
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
if anyList=="two":
return helperfunc(finalDict,myList2)
if anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper)
This will help you to exit your 3 nested loops as it was mentioned in comments.
Because in the negative case on first wrong occurrence you don't need to check anything else.
Use return to break all of your loop. Having an else statement is not necessary if you don't have any if statement to begin with.
def validationHelper(myDict, myList):
for item in myList:
if item in myDict.values():
return ("String is valid")
return ("String is NOT valid")
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
elif anyList=="two":
return helperfunc(finalDict,myList2)
elif anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper.true)
Using elif instead of multiple if is a better practice. Be careful with indentions next time.
Also you might want to check .keys() and .values()
You can replace:
for key in myDict:
for value in myDict[key][0]:
with:
for value in myDict.values():
The other answers give a good explanation of how to break out of multiple loops. But you could also simplify your code by using Python's built-in functions and list comprehensions, like this:
def validationHelper(myDict, myList):
if any(v in myList for val in myDict.values() for v in val[0]):
validationHelper.true="String is valid"
else:
validationHelper.true="Warning: String is NOT valid"
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
if anyList=="two":
return helperfunc(finalDict,myList2)
if anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper.true)
This should be as efficient as your code, since any short circuits at the first match. And it may be a little more readable. (Note that multi-level list comprehensions go in the same order as regular for loops.)

What type of loop to use with this pseudo code

This is for a python project I'm working on. I'm still learning the language, but I have hit a stump here. Any help is greatly appreciated. Here is my pseudo code:
variable1 = (returned function() value)
listItem = []
<start loop>
If value of variable1 IS NOT in listItem:
listItem.append(assign value from variable1)
else:
go back to start of loop
print listItem(all items)
I am confused if its best to use a for, while, or if statement here. I have tried with all three, but I get various errors. I am not seeing something...
You want to convert a list to a unique list:
>>> results = function()
>>> unique = []
>>> for result in results:
... if result not in unique:
... unique.append(result)
set is good for uniqueness, and you can convert it to a list easily:
>>> unique = list(set(results))
However, this won't keep the order of the original results.
Python doesn't have an ordered set, but it does have an ordered dictionary, which you can abuse by using it's keys as an ordered set:
>>> from collections import OrderedDict
>>> ordered_unique = OrderedDict((key, key) for key in results).keys()
Currently all you need is the if statement, you don't need the loop or the else statement.
If I understand you correctly, you want to search listItem for ONE variable (variable1), and if it doesn't contain that variable, you want to append it to the list. However, it seems like your question is missing something. Perhaps you are trying to search listItem for multiple variables?
Thanks for the insight everyone. I have figured it out. I needed to use a while loop for this task. Here is my solution.
variable0 = <null value>
listItem = [empty list]
variable1 = 0 (required for while loop expression)
while variable1 is less than 0:
variable0 = (returned random function() value)
if variable0 is not in listItem:
Append variable0 value to listItem
increase value of variable1 by 1
print contents of listItem
Thanks again for all of your help.

Iterating over list to add text values to Python ElementTree

I seem to be having a syntax problem in Python...
OV: I'm receiving CSV input as a tuple that I want to add as text inside ElementTree elements. Upon the first iteration of the loop, the data values (starting at [0]) should be added to the elements. Incrementing to the next data point in the list for each iteration and building new elements.
Here is code block so far:
for r in results:
for key, value in r.iteritems():
if key == "foo":
listing = value.split(',')
type = ET.SubElement(root, "TYPE")
type.text = +listing[0]+
value = ET.SubElement(type, "Value")
value.text = +listing[1].lstrip()+
If this is something simple, please forgive me. I am but just starting out in the quest to conquer :)

Categories