list append replaces previously appended value [duplicate] - python

This question already has answers here:
List on python appending always the same value [duplicate]
(5 answers)
Creating a list of dictionaries results in a list of copies of the same dictionary
(4 answers)
Closed 4 years ago.
I am trying to append dictionaries to a list here, problem is after appending both "Chrome" and "Firefox" values to the "list" i see only firefox.exe in list for both entries ..
any help is really appreciated.
See the print statement of dictionary where both values are different.
MyItems = ["ChromeSetup.exe","firefox.exe"]
listofitems = [{"appId": "ChromeID", 'id': "0","name": 'ChromeSetup.exe','_id': 'ChromeUnique'},{"appId": "FireFoxID", 'id': "0","name": 'firefox.exe','_id': 'FireFoxUnique'} ]
__id = ""
appId = ""
result = []
Dict = {"installerParameters":"","managedApp":{"_id":__id, "appId":appId},"postInstallAction":0,"postInstallScript":{"_id":"0"},"preInstallScript":{"_id":"0"}}
for app in MyItems:
for items in listofitems:
if items['name'] == app:
Dict["managedApp"]["_id"] = items['_id']
Dict["managedApp"]["appId"] = items['appId']
print("Dictionery",Dict)
result.append(Dict)
break
print("See the List", result)
Result:
Dictionery {'installerParameters': '', 'managedApp': {'_id': 'ChromeUnique', 'appId': 'ChromeID'}, 'postInstallAction': 0, 'postInstallScript': {'_id': '0'}, 'preInstallScript': {'_id': '0'}}
Dictionery {'installerParameters': '', 'managedApp': {'_id': 'FireFoxUnique', 'appId': 'FireFoxID'}, 'postInstallAction': 0, 'postInstallScript': {'_id': '0'}, 'preInstallScript': {'_id': '0'}}
See the List [{'installerParameters': '', 'managedApp': {'_id': 'FireFoxUnique', 'appId': 'FireFoxID'}, 'postInstallAction': 0, 'postInstallScript': {'_id': '0'}, 'preInstallScript': {'_id': '0'}}, {'installerParameters': '', 'managedApp': {'_id': 'FireFoxUnique', 'appId': 'FireFoxID'}, 'postInstallAction': 0, 'postInstallScript': {'_id': '0'}, 'preInstallScript': {'_id': '0'}}]

Define the dictionary in the for loop. You are currently writing to same dictionary object, and list holds reference to this object which itself is a reference. As a result you keep modifying the same object.
MyItems = ["ChromeSetup.exe","firefox.exe"]
listofitems = [{"appId": "ChromeID", 'id': "0","name": 'ChromeSetup.exe','_id': 'ChromeUnique'},{"appId": "FireFoxID", 'id': "0","name": 'firefox.exe','_id': 'FireFoxUnique'} ]
__id = ""
appId = ""
result = []
for app in MyItems:
for items in listofitems:
if items['name'] == app:
# I would try to find a better var name.
Dict = {"installerParameters":"","managedApp":{"_id":__id, "appId":appId},"postInstallAction":0,"postInstallScript":{"_id":"0"},"preInstallScript":{"_id":"0"}}
Dict["managedApp"]["_id"] = items['_id']
Dict["managedApp"]["appId"] = items['appId']
print("Dictionery",Dict)
result.append(Dict)
break
print("See the List", result)

Your dictionary object Dict is being overwritten during the second run of the loop. This is happening because you have defined the Dict above the loop. Better to define the Dict inside the loop.

Related

How to take from key value and take from this value another value

How can i get needed value, because i send post request to other site and cant edit answer from site.
I have this dict from responded content:
{'username': 'DeadFinder', 'subscriptions': [{'subscription': 'default', 'expiry': '1635683460'}], 'ip': 'not at this life'}
How you can see in this dict there is a key subscriptions, i'm need value expiry(this is timestamp) but how can i get this value if when i'm trying to call this value i'm not see any results (code not gives needed value), maybe any variants how to get this value? I'm not finded anything like this.
Maybe my small part of code can smally help you but i doubt.
data1 = {f"hwid":"", "type":"login", "username": {username}, "pass": {password},
"sessionid":f"{response_cut2}", "name":"test_app", "ownerid":"5OLbm5S3fS"}
url1 = "nope"
response1 = requests.post(url1, data1)
data = response1.json()
#get = data.get('expiry')
file_write = open("test.txt", "w")
file_write.write(str(data))
file_write.close()
for key in data.keys():
if key == 'info':
print (data[key])
Are you trying to achieve this as result ?
data = {'username': 'DeadFinder', 'subscriptions': [{'subscription': 'default', 'expiry': '1635683460'}], 'ip': 'not at this life'}
print(data['subscriptions'][0]['expiry'])
# first get 'subscriptions' which returns an array,
# so use [0] to get this dict {'subscription': 'default', 'expiry': '1635683460'}
# then get 'expiry'
EDIT : In case subscriptions has multiple values then use for loop
subscriptions = data['subscriptions']
for subscription in subscriptions:
print(subscription['expiry'])
Output
1635683460

Looping through a function

I am struggling with figuring out the best way to loop through a function. The output of this API is a Graph Connection and I am a-little out of my element. I really need to obtain ID's from an api output and have them in a dict or some sort of form that I can pass to another API call.
**** It is important to note that the original output is a graph connection.... print(type(api_response) does show it as a list however, if I do a print(type(api_response[0])) it returns a
This is the original output from the api call:
[{'_from': None, 'to': {'id': '5c9941fcdd2eeb6a6787916e', 'type': 'user'}}, {'_from': None, 'to': {'id': '5cc9055fcc5781152ca6eeb8', 'type': 'user'}}, {'_from': None, 'to': {'id': '5d1cf102c94c052cf1bfb3cc', 'type': 'user'}}]
This is the code that I have up to this point.....
api_response = api_instance.graph_user_group_members_list(group_id, content_type, accept,limit=limit, skip=skip, x_org_id=x_org_id)
def extract_id(result):
result = str(result).split(' ')
for i, r in enumerate(result):
if 'id' in r:
id = (result[i+1].translate(str.maketrans('', '', string.punctuation)))
print( id )
return id
extract_id(api_response)
def extract_id(result):
result = str(result).split(' ')
for i, r in enumerate(result):
if 'id' in r:
id = (result[i+8].translate(str.maketrans('', '', string.punctuation)))
print( id )
return id
extract_id(api_response)
def extract_id(result):
result = str(result).split(' ')
for i, r in enumerate(result):
if 'id' in r:
id = (result[i+15].translate(str.maketrans('', '', string.punctuation)))
print( id )
return id
extract_id(api_response)
I have been able to use a function to extract the ID's but I am doing so through a string. I am in need of a scalable solution that I can use to pass these ID's along to another API call.
I have tried to use a for loop but because it is 1 string and i+1 defines the id's position, it is redundant and just outputs 1 of the id's multiple times.
I am receiving the correct output using each of these functions however, it is not scalable..... and just is not a solution. Please help guide me......
So to solve the response as a string issue I would suggest using python's builtin json module. Specifically, the method .loads() can convert a string to a dict or list of dicts. From there you can iterate over the list or dict and check if the key is equal to 'id'. Here's an example based on what you said the response would look like.
import json
s = "[{'_from': None, 'to': {'id': '5c9941fcdd2eeb6a6787916e', 'type': 'user'}}, {'_from': None, 'to': {'id': '5cc9055fcc5781152ca6eeb8', 'type': 'user'}}, {'_from': None, 'to': {'id': '5d1cf102c94c052cf1bfb3cc', 'type': 'user'}}]"
# json uses double quotes and null; there is probably a better way to do this though
s = s.replace("\'", '\"').replace('None', 'null')
response = json.loads(s) # list of dicts
for d in response:
for key, value in d['to'].items():
if key == 'id':
print(value) # or whatever else you want to do
# 5c9941fcdd2eeb6a6787916e
# 5cc9055fcc5781152ca6eeb8
# 5d1cf102c94c052cf1bfb3cc

For loop is overwriting dictionary values in list [duplicate]

This question already has answers here:
Filling a python dictionary in for loop returns same values
(2 answers)
Closed 5 years ago.
Issue
I've made a for loop reading the contents of a list however when assigning two values to a dictionary and then appending that output to a list, the next value overwrites everything in the list
Desired outcome
I want to append multiple dictionaries to a list so when I run a for loop and print everything related to 'ip' it will print all the values associated with the dictionary value 'ip'.
Code
device = { 'ip': '', 'mac': '', 'username': 'admin', 'password': [], 'device type': '', }
listofdevices = []
def begin():
file = open("outputfromterminal")
contents = file.read()
contents = contents.split(',')[1:]
for x in contents:
# do some text stripping
x = x.split(' ')
device['ip']=x[0]
device['mac']=x[1]
listofdevices.append(device)
Sample code
the 1st index of contents is:
x[0] = '10.10.10.1'
x[1] = 'aa:bb:cc:dd'
The 2nd index of contents is:
x[0] = '20.20.20.1'
x[1] = 'qq:ww:ee:ee:rr'
What actually happens
listofdevices[0] 'ip': 20.20.20.1, 'mac': 'qq:ww:ee:ee:rr'
listofdevices[1] 'ip': 20.20.20.1, 'mac': 'qq:ww:ee:ee:rr'
Try this code. Each device was trying to edit the same copy of a dictionary.
listofdevices = []
def begin():
with open("outputfromterminal", 'r') as f:
contents = f.read().split(',')[1:]
for line in contents:
# do some text stripping
line = line.split(' ')
device = { 'ip': line[0],
'mac': line[1],
'username': 'admin',
'password': [],
'device type': '',
}
listofdevices.append(device)
You are not creating a new dictionary object each time. You are simply mutating the same object within each iteration. Try deep copying the dictionary using the copy module. Then after obtaining this copy, mutate it and append to list:
import copy
device = { 'ip': '', 'mac': '', 'username': 'admin', 'password': [], 'device type': '', }
listofdevices = []
def begin():
file = open("outputfromterminal")
contents = file.read()
contents = contents.split(',')[1:]
for x in contents:
device = copy.deepcopy(device) #creates a deep copy of the values of previous dictionary.
#device now references a completely new object
# do some text stripping
x = x.split(' ')
device['ip']=x[0]
device['mac']=x[1]
listofdevices.append(device)
The issue is due to the appending of the list. When you append an item(in your case a dictionary). It does not create a dictionary, But it simply places the reference.
It should work if you can initialise the dictionary in the for loop every time, So a new reference is created.
listofdevices = []
def begin():
file = open("outputfromterminal")
contents = file.read()
contents = contents.split(',')[1:]
for x in contents:
# do some text stripping
x = x.split(' ')
device = { 'ip': '', 'mac': '', 'username': 'admin', 'password': [], 'device type': '', }
device['ip']=x[0]
device['mac']=x[1]
listofdevices.append(device)

Unable to access dict values indjango view

I want to save an array of objects passed from javascript through ajax to me database. This is my view code:
data2 = json.loads(request.raw_get_data)
for i in data2:
print(key)
obj = ShoppingCart(quantity = i.quantity , user_id = 3, datetime = datetime.now(), product_id = i.pk)
obj.save()
return render_to_response("HTML.html",RequestContext(request))
After the first line, i get this in my dictionary:
[{'model': 'Phase_2.product', 'fields': {'name': 'Bata', 'category': 2, 'quantity': 1, 'subcategory': 1, 'count': 2, 'price': 50}, 'imageSource': None, 'pk': 1}]
(Only one object in the array right now)
I want to be able access individual fields like quantity, id, etc in order to save the data to my database. When i debug this code, it gives a name error on 'i'. I also tried accessing the fields like this: data2[0].quantity but it gives this error: {AttributeError}dict object has no attribute quantity.
Edited code:
for i in data2:
name = i["fields"]["name"]
obj = ShoppingCart(quantity = i["fields"]["quantity"] , user_id = 3, datetime = datetime.now(), product_id = i["fields"]["pk"])
obj.save()
It might help you to visualise the returned dict with proper formatting:
[
{
'model': 'Phase_2.product',
'fields': {
'name': 'Bata',
'category': 2,
'quantity': 1,
'subcategory': 1,
'count': 2,
'price': 50
},
'imageSource': None,
'pk': 1
}
]
The most likely reason for your error is that you are trying to access values of of the inner 'fields' dictionary as if they belong to the outer i dictionary.
i.e.
# Incorrect
i["quantity"]
# Gives KeyError
# Correct
i["fields"]["quantity"]
Edit
You have the same problem in your update:
# Incorrect
i["fields"]["pk"]
# Correct
i["pk"]
The "pk" field is in the outer dictionary, not the inner "fields" dictionary.
You may try:
i['fields']['quantity']
The json.loads() returns you a dictionary, which should be accessed by key.

Update and create a multi-dimensional dictionary in Python

I am parsing JSON that stores various code snippets and I am first building a dictionary of languages used by these snippets:
snippets = {'python': {}, 'text': {}, 'php': {}, 'js': {}}
Then when looping through the JSON I'm wanting add the information about the snippet into its own dictionary to the dictionary listed above. For example, if I had a JS snippet - the end result would be:
snippets = {'js':
{"title":"Script 1","code":"code here", "id":"123456"}
{"title":"Script 2","code":"code here", "id":"123457"}
}
Not to muddy the waters - but in PHP working on a multi-dimensional array I would just do the following (I am lookng for something similiar):
snippets['js'][] = array here
I know I saw one or two people talking about how to create a multidimensional dictionary - but can't seem to track down adding a dictionary to a dictionary within python. Thanks for the help.
This is called autovivification:
You can do it with defaultdict
def tree():
return collections.defaultdict(tree)
d = tree()
d['js']['title'] = 'Script1'
If the idea is to have lists, you can do:
d = collections.defaultdict(list)
d['js'].append({'foo': 'bar'})
d['js'].append({'other': 'thing'})
The idea for defaultdict it to create automatically the element when the key is accessed. BTW, for this simple case, you can simply do:
d = {}
d['js'] = [{'foo': 'bar'}, {'other': 'thing'}]
From
snippets = {'js':
{"title":"Script 1","code":"code here", "id":"123456"}
{"title":"Script 2","code":"code here", "id":"123457"}
}
It looks to me like you want to have a list of dictionaries. Here is some python code that should hopefully result in what you want
snippets = {'python': [], 'text': [], 'php': [], 'js': []}
snippets['js'].append({"title":"Script 1","code":"code here", "id":"123456"})
snippets['js'].append({"title":"Script 1","code":"code here", "id":"123457"})
print(snippets['js']) #[{'code': 'code here', 'id': '123456', 'title': 'Script 1'}, {'code': 'code here', 'id': '123457', 'title': 'Script 1'}]
Does that make it clear?

Categories

Resources