a = [ 'abc=lalalla', 'appa=kdkdkdkd', 'kkakaka=oeoeoeo']
d = dict(s.split('=') for s in a)
print d
Output:
{'kkakaka': 'oeoeoeo', 'abc': 'lalalla', 'appa': 'kdkdkdkd'}
http://codepad.org/bZ8lGuHE
Answer from Demian Brecht on Stack Overflowa = [ 'abc=lalalla', 'appa=kdkdkdkd', 'kkakaka=oeoeoeo']
d = dict(s.split('=') for s in a)
print d
Output:
{'kkakaka': 'oeoeoeo', 'abc': 'lalalla', 'appa': 'kdkdkdkd'}
http://codepad.org/bZ8lGuHE
In addition, make sure you limit the splits to 1, in case the right-hand side contains an '='.
d = dict(s.split('=',1) for s in a)
arrays - How to convert string to key value in python - Stack Overflow
python - Parsing a string of key-value pairs as a dictionary - Code Review Stack Exchange
python - Convert strings of key-multiple values into key-value pairs - Stack Overflow
Convert string into key-value pair array
Your string looks very similar to the YAML syntax. Indeed it is almost valid syntax for an associative list, there are only spaces missing after the :. So, why not use a YAML parser?
import yaml
data = """
41:n
43:n
44:n
46:n
47:n
49:n
50:n
51:n
52:n
53:n
54:n
55:cm
56:n
57:n
58:n"""
print(yaml.load(data.replace(":", ": ")))
# {41: 'n',
# 43: 'n',
# 44: 'n',
# 46: 'n',
# 47: 'n',
# 49: 'n',
# 50: 'n',
# 51: 'n',
# 52: 'n',
# 53: 'n',
# 54: 'n',
# 55: 'cm',
# 56: 'n',
# 57: 'n',
# 58: 'n'}
You might have to install it first, which you can do via pip install yaml.
You have too much logic in the dict comprehension:
{int(line.split(":")[0]):line.split(":")[1] for line in data.split("\n") if len(line.split(":"))==2}
First of all, let's expand it to a normal for-loop:
>>> result = {}
>>> for line in data.split("\n"):
... if len(line.split(":"))==2:
... result[int(line.split(":")[0])] = line.split(":")[1]
>>> result
I can see that you use the following check if len(line.split(":"))==2: to eliminate the first blank space from the data.split("\n"):
>>> data.split("\n")
['',
'41:n',
'43:n',
...
'58:n']
But the docs for str.split advice to use str.split() without specifying a sep parameter if you wanna discard the empty string at the beginning:
>>> data.split()
['41:n',
'43:n',
...
'58:n']
So, now we can remove unnecessary check from your code:
>>> result = {}
>>> for line in data.split():
... result[int(line.split(":")[0])] = line.split(":")[1]
>>> result
Here you calculate line.split(":") twice. Take it out:
>>> result = {}
>>> for line in data.split():
... key, value = line.split(":")
... result[int(key)] = value
>>> result
This is the most basic version. Don't put it back to a dict comprehension as it will still look quite complex. But you could make a function out of it. For example, something like this:
>>> def to_key_value(line, sep=':'):
... key, value = line.split(sep)
... return int(key), value
>>> dict(map(to_key_value, data.split()))
{41: 'n',
43: 'n',
...
58: 'n'}
Another option that I came up with:
>>> from functools import partial
>>> lines = data.split()
>>> split_by_colon = partial(str.split, sep=':')
>>> key_value_pairs = map(split_by_colon, lines)
>>> {int(key): value for key, value in key_value_pairs}
{41: 'n',
43: 'n',
...
58: 'n'}
Also, if you don't want to keep in memory a list of results from data.split, you might find this helpful: Is there a generator version of string.split() in Python?
You can combine both cases by concatenating your b.name value with an empty array:
b.options = [].concat(b.name).map(function(v,i) {
return [v, b.value[i]];
});
in that way, you will get an array from b.name when is a string and also when it is an array already. You may need to handle the case when b or b.name is undefined though. Or you can use more general zip function:
var zip = function(arr1, arr2) {
var a = [].concat(arr1);
var b = [].concat(arr2);
var len = Math.min(a.length, b.length)
return a.slice(0, len).map(function(item, i){
return [a[i], b[i]];
});
}
b.options = zip(b.name, b.value);
Mind in that case that the returned array will have the length of the shortest array.
if b.name has length attribute,you can use 'call'
if(Array.isArray(b.name)){
b.options = Array.prototype.map.call(b.name,function(v,i) {
return [v, b.value[i]];
})
}else{
b.options = Array.prototype.map.call(b.name,function(v,i) {
return [v, b.value[i]];
})
}
I'm trying to put together a small script that pulls and processes DNS information. I'm using dnspython to make the calls and that part is working find. Below is an example of the string I get back from it:
"v=DMARC1; p=reject; sp=reject; pct=100; fo=1; adkim=r; aspf=r; rua=mailto:me@example.net,mailto:you@example.net; ruf=mailto:dmarc@example.net"
How can I take that string and turn it into an array (I think it would be a dict in python) like this:
dns_data = {
'v' : 'DMARC1',
'p' : 'reject',
'sp' : 'reject',
'pct' : '100',
'fo' : '1',
'adkim' : 'r',
'aspf' : 'r',
'rua' : 'mailto:me@example.net,mailto:you@example.net',
'ruf' : 'mailto:dmarc@example.net'
}Using strip and split I managed to get the string to a list like this:
['v=DMARC1', 'p=reject', 'sp=reject', 'pct=100', 'fo=1', 'adkim=r', 'aspf=r', 'rua=mailto:me@example.net,mailto:you@example.net', 'ruf=mailto:dmarc@example.net']
but I can't seem to figure out how to go from there to the dict and now I'm wondering if I'm just going about this the hard way and missing something simple.
First off, you should standardize your names, Key and value don't follow the same naming rules, or if they do, they're not apparent to me.
And so I'd recommend that you name your things in lower_snake_case, to adhere to PEP8.
After this I'd use str.strip rather than str.split.
And use a list comprehension to change both the key and value without having to duplicate the code, which can remove the key and value variables altogether.
This can leave you with:
item = [i.strip() for i in line.split('=')]
CQ_options[item[0]] = item[1]
If you want to stick with using key and value however, you need to make sure that line.split('=') will only return two items. You can make sure it'll return a max of two items with the optional parameter, and since we'd already error if there's not at least a single =, then you can use:
key, value = [i.strip() for i in line.split('=', 1)]
CQ_options[key] = value
You can use a dict comprehension if you have multiple items in a list, for example:
a = ["Random = 1", "Ran = 3"]
print {k.strip(): int(v.strip()) for k, v in (i.split("=") for i in a)}
>>> {'Ran': 3, 'Random': 1}
If you want to update an existing dictionary d:
d.update({k.strip(): int(v.strip()) for k, v in (i.split("=") for i in a)})
You can use the $ at the start of a line to identify this is a new key, append it to the keys list and append a new blank string to the values list. Then every time you have a line which doesnt start with a $ you concat that value on to the last element of values as this line must be related to the current key. only when you read a new key do you create a new blank values element.
data = "$key\nsome value\n$another_key\nanother longer\nvalue\n"
keys = []
values = []
for line in data.split('\n'):
if line.startswith('$'):
keys.append(line)
values.append("")
else:
values[-1] += line
print(keys, values)
Output
['$key', '$another_key'] ['some value', 'another longervalue']
text = "$key\nsome value\n$another_key\nanother longer\nvalue"
key = []
value = []
for i in text.split('\n'):
if i[0]=='$':
key.append(i)
else:
value.append(i)
Use re.findall():
dict(re.findall(r'(\w+)="([^"]+)"', twikiattribs))
re.findall(), when presented with a pattern with multiple capturing groups, returns a list of tuples, each nested tuple containing the captured groups. dict() happily takes that output and interprets each nested tuple as a key-value pair.
Demo:
>>> import re
>>> twikiattribs = 'author="PersonsName" date="1183050420" format="1.1" version="1.2"'
>>> re.findall(r'(\w+)="([^"]+)"', twikiattribs)
[('author', 'PersonsName'), ('date', '1183050420'), ('format', '1.1'), ('version', '1.2')]
>>> dict(re.findall(r'(\w+)="([^"]+)"', twikiattribs))
{'date': '1183050420', 'format': '1.1', 'version': '1.2', 'author': 'PersonsName'}
re.split() also behaves differently based on capturing groups; the text on which you split is included in the output if grouped. Compare the output with and without the capturing group:
>>> re.split('(=?" ?)', twikiattribs)
['author', '="', 'PersonsName', '" ', 'date', '="', '1183050420', '" ', 'format', '="', '1.1', '" ', 'version', '="', '1.2', '"', '']
>>> re.split('=?" ?', twikiattribs)
['author', 'PersonsName', 'date', '1183050420', 'format', '1.1', 'version', '1.2', '']
The re.findall() output is far easier to convert to a dictionary however.
you can also do it without re in one line:
>>> data = '''author="PersonsName" date="1183050420" format="1.1" version="1.2"'''
>>> {k:v.strip('"') for k,v in [i.split("=",1) for i in data.split(" ")]}
{'date': '1183050420', 'format': '1.1', 'version': '1.2', 'author': 'PersonsName'}
if whitespaces are allowed inside the values you can use this line:
>>> {k:v.strip('"') for k,v in [i.split("=",1) for i in data.split('" ')]}
You can just use eval or ast.literal_eval appending opening and closing curly braces at the beginning and the end of your string representation.
>>> import ast
>>> ast.literal_eval('{'+test_str+'}')
{1: 20, 3: 4, 5: 30}
s="1:20,3:4,5:30"
d ={}
l =s.split(",")
l1=[]
for i in l:
l2 = i.split(":")
l1.append(l2)
l2 = []
for j in l1:
d[j[0]] =j[1]
What this code does is that it first converts string into a dictionary spliting it by"," and then t takes each element of the list and converts it into the dictionary taking 1st element as key and last element as its value