我有一个输入文件,我可以从中构建我的字典
一般格式
<IP_1>
KEY_1=VALUE_1
KEY_2=VALUE_2
<IP_2>
KEY_1=VALUE_1
KEY_2=VALUE_2
实施例
192.168.1.1
USER_NAME=admin
PASSWORD=admin123
192.168.1.2
USER_NAME=user
PASSWORD=user123
预期字典应如下所示:
>>print dictionary_of_ip
{'192.168.1.1':{'USER_NAME'='admin','PASSWORD'='admin123'},
'192.168.1.2':{'USER_NAME'='user','PASSWORD'='user123'}}
本质上是字典中的字典
以下是我的代码:
def generate_key_value_pair(filePath, sep='='):
dict_of_ip = {}
slave_properties = {}
with open(filePath, "rt") as f:
for line in f:
stripped_line = line.strip()
if stripped_line and stripped_line[0].isdigit():
#print 'Found Ip'
ip = stripped_line
dict_of_ip[ip] = ''
elif stripped_line and stripped_line[0].isupper():
#print "Found attributes")
key_value = stripped_line.split(sep)
key = key_value[0].strip()
value = key_value[1].strip()
slave_properties[key] = value
dict_of_ip[ip] = slave_properties
return dict_of_ip
我能够按预期获得第一个IP及其属性,但第二个IP的第二组值将覆盖第一个。
>>print dict_of_ip
{'192.168.1.1': {'USER_NAME': 'user', 'PASSWORD': 'user123'},
'192.168.1.2': {'USER_NAME': 'user', 'PASSWORD': 'user123'}}
dict_of_ip[ip] = slave_properties
导致覆盖。如何防止'192.168.1.2'
键覆盖第一个值?
答案 0 :(得分:0)
试试这个:
def generate_key_value_pair(filePath, sep='='):
dict_of_ip = {}
with open(filePath, "rt") as f:
for line in f:
stripped_line = line.strip()
if stripped_line and stripped_line[0].isdigit():
#print 'Found Ip'
slave_properties = {}
ip = stripped_line
dict_of_ip[ip] = ''
elif stripped_line and stripped_line[0].isupper():
#print "Found attributes")
key_value = stripped_line.split(sep)
key = key_value[0].strip()
value = key_value[1].strip()
slave_properties[key] = value
dict_of_ip[ip] = slave_properties
return dict_of_ip
你在哪里使用相同的(修改的)dict
。我没有故意更改您的代码逻辑,只是将slave_properties = {}
更改为应该的位置
您甚至可以删除slave_properties
并单独使用dict
def generate_key_value_pair(filePath, sep='='):
dict_of_ip = {}
with open(filePath, "rt") as f:
for line in f:
stripped_line = line.strip()
if stripped_line and stripped_line[0].isdigit():
#print 'Found Ip'
ip = stripped_line
dict_of_ip[ip] = {}
elif stripped_line and stripped_line[0].isupper():
#print "Found attributes")
key_value = stripped_line.split(sep)
key = key_value[0].strip()
value = key_value[1].strip()
dict_of_ip[ip][key] = value
return dict_of_ip
答案 1 :(得分:0)
你没有在循环中执行slave_properties = {}
,所以当你认为你正在用
slave_properties[key] = value
dict_of_ip[ip] = slave_properties
答案 2 :(得分:0)
如果使用Python的高性能数据类型,这将变得更容易,更有效。例如,这里的代码与defaultdict相同,而不是创建自己的集合类型。
from collections import defaultdict
dict_of_ip = defaultdict(dict) # This creates a dictionary of dictionaries for you.
ip = None
for line in f:
stripped_line = line.strip()
if stripped_line and stripped_line[0].isdigit():
ip = stripped_line # The value for the ip only changes if a new
# IP is detected. Otherwise the algorithm proceeds
# with the older IP address to the nested dict.
elif stripped_line and stripped_line[0].isupper():
key_value = stripped_line.split(sep)
key = key_value[0].strip()
value = key_value[1].strip()
dict_of_ip[ip][key] = value # IP set in the earlier if-loop.
更具体地说,您收到错误的原因是您为每个子字典编辑了相同的slave_properties
字典。因此,一个人的变化传播到另一个人。
答案 3 :(得分:0)
您可以选择正则表达方式与词典理解相结合:
import re
string = """
192.168.1.1
USER_NAME=admin
PASSWORD=admin123
192.168.1.2
USER_NAME=user
PASSWORD=user123
"""
regex = re.compile(r"""
^
(?P<ip>\d+\.\d+\.\d+\.\d+)[\n\r]
USER_NAME=(?P<user>.+)[\r\n]
PASSWORD=(?P<password>.+)
""", re.MULTILINE | re.VERBOSE)
users = {match.group('ip'):
{'USER_NAME': match.group('user'),
'PASSWORD': match.group('password')}
for match in regex.finditer(string)}
print(users)
# {'192.168.1.2': {'USER_NAME': 'user', 'PASSWORD': 'user123'}, '192.168.1.1': {'USER_NAME': 'admin', 'PASSWORD': 'admin123'}}
答案 4 :(得分:0)
在识别出IP地址后,将public static node* FindMin(node* root){ //FindMax would be nearly identical
node* minValue = root;
while(node->Next){
if(node->Value < minValue->Value)
minValue = node;
}
return minValue;
}
public static node* CountingSortArray(node* linklist){
node* root = linkedlist
node* min = FindMin(linklist);
node* max = FindMax(linklist);
int[] counts = new int[max->Value - min->Value + 1];
while(root != NULL){
counts[root->Value] += 1;
root = root->Next;
}
int i = 0;
root = linkedlist;
while(ptr != NULL){
if(counts[i] == 0)
++i;
else{
root->Value = i;
--count[i];
root = root->Next;
}
}
}
void push(node** head, int new_data){
node* newNode = new node();
newNode->Value = new_data;
newNode->Next = (*head);
(*head) = newNode;
}
void printList(node* root){
while(root != NULL){
printf(%d ", root->Value);
root = root->Next;
}
printf("\n");
}
int main(void){
node* myLinkedList = NULL;
push(&head, 0);
push(&head, 1);
push(&head, 0);
push(&head, 2);
push(&head, 0);
push(&head, 2);
printList(myLinkedList);
CountingSortArray(myLinkedList);
printList(myLinkedList);
}
的初始化移至右侧。这样,对于遇到的每一个,它都将为空(我也删除了slave_properties
所不必要的初始化。)
dict_of_ip[ip]
输出:
from pprint import pprint
def generate_key_value_pair(filePath, sep='='):
dict_of_ip = {}
with open(filePath, "rt") as f:
for line in f:
line = line.strip()
if line and line[0].isdigit(): # ip?
slave_properties = {} # initialize
ip = line
elif line and line[0].isupper():
key_value = line.split(sep)
key = key_value[0].strip()
value = key_value[1].strip()
slave_properties[key] = value
dict_of_ip[ip] = slave_properties
return dict_of_ip
result = generate_key_value_pair('ips.txt')
pprint(result)
答案 5 :(得分:0)
使用切片和dictcomp的紧凑解决方案:
with open("data.txt", "r") as f:
f = [i.strip() for i in f.readlines()]
ipdict = {ip: {'USER_NAME': user[10:], 'PASSWORD': password[9:]}
for ip, user, password in zip(f[0::4], f[1::4], f[2::4])}