在Python中使用字典而不是动态变量名 [英] Dictionary use instead of dynamic variable names in Python

查看:192
本文介绍了在Python中使用字典而不是动态变量名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个长的文本文件有卡车配置。在每一行中,卡车的一些属性被列为字符串。每个属性在字符串中都有自己的固定宽度空间,例如:

  2 chracters =轴数
2字符=第一轴的重量
2个字符=第二轴的重量
...
2个字符=最后一个轴的重量
2个字符=第一个轴的长度间距(间距是指轴之间的距离)
2个字符=第二轴间距的长度
...
2个字符=最后一个轴间距的长度

举个例子:

  031028331004 

指:

 code>轴数= 3 
第一轴重量= 10
第二轴重量= 28
第三轴重量= 33
第一间距= 10
秒间距= 4

现在,您有关于我的文件结构的想法,这里是我的问题:我会喜欢将这些卡车分成不同的列表,并以轴间距表示列表。假设我使用布尔类型的方法,如果间距小于6,则布尔值为1,如果大于6,则布尔值为0.为了说明,三轴卡车的可能结果将变为: / p>

  00 #Both间距> 6 
10#第一个间距< 6,第二> 6
01#第一个间距> 6, 6
11#两个间距< 6

现在,您看到3轴卡车的结果不会太多。然而,如果我有一个12轴卡车,可能组合的数量是haywire。事实是,在现实中,您将看不到12轴卡车的所有可能的轴距组合。有一些组合(我不知道哪些,但是想出来是我的目标),其数量远小于可能的组合数。



我希望代码创建列表,并使用定义上述属性的字符串填充它们,只有存在这样的组合。我想也许我应该创建一个变量名称列表,如:

  truck_0300 [] 
truck_0301 []
truck_0310 []
truck_0311 []

。然而,从我在SF和其他来源读到的东西,这是非常不鼓励的。您将如何使用字典概念?我知道字典就像二维数组,有一个键(在我的情况下,键将是像truck_0300,truck_0301等)和值对(在我的情况下,这些值可能是包含实际字符串的列表属于相应的卡车类型),但是我无法弄清楚如何创建该字典,并使用变量键和值填充。



任何见解都将受到欢迎!
感谢一堆!

解决方案

你绝对是正确的,尝试创建动态变量。字典通常是随着时间的推移建立对象集合的答案,并引用他们...



我不完全理解您的应用程序和格式,但在一般来说,定义和使用你的字典看起来像这样:

  trucks = {} 
truck ['0300' ] = ['a']
卡车['0300']。append('c')
卡车['0300']。extend(['c','d'])

aTruck =卡车['0300']

现在,因为每一个都应该您的字符串列表,您可能只想使用defaultdict,并告诉它使用列表作为非存在键的默认值:

  from collections import defaultdict 

trucks = defaultdict(list)
trucks ['0300']
#[]
请注意,即使这是一个不包含条目的全新字幕,truck_0300键仍然会返回一个新的列表。这意味着你不需要检查钥匙。只需添加:

  trucks = defaultdict(list)
trucks ['0300']。append('a')

defaultdict 可能是你想要的,因为你根本不需要预定义键。



获取最大值的密钥



从您的评论中,以下是一个如何使用字典的最大值获取密钥的示例。这很简单,因为您只需使用 max 并定义如何确定用于比较的密钥:

  d = {'a':10,'b':5,'c':50} 
print max(d.iteritems(),key = lambda ,v):v)
#('c',50)
d ['c'] = 1
print max(d.iteritems(),key = lambda(k,v) :v)
#('a',10)

你所要做的只是定义如何生成比较键。在这种情况下,我只是告诉它取值作为关键。对于真正简单的关键功能,您只需要告诉它从对象中提取索引或属性,您可以使用运算符模块使其更有效,以便关键功能是C,而不是python作为lambda:

 从运算符import itemgetter 
...
print max(d.iteritems(),key = itemgetter(1))
#('c',50)

itemgetter 创建一个新的可调用函数,将从循环传入的元组中拉出第二个项。



现在假设每个值实际上是一个列表(类似于你的结构)。我们将列出一个数字列表,并且您想要找到具有最大总数列表的键:

  d = {'a':range(1,5),'b':range(2,4),'c':range(5,7)} 
print max(d.iteritems(),key = lambda(k,v):sum(v))
#('c',[5,6])


I have a long text file having truck configurations. In each line some properties of a truck is listed as a string. Each property has its own fixed width space in the string, such as:

2 chracters = number of axles
2 characters = weight of the first axle
2 characters = weight of the second axle
...
2 characters = weight of the last axle
2 characters = length of the first axle spacing (spacing means distance between axles)
2 characters = length of the second axle spacing
...
2 characters = length of the last axle spacing

As an example:

031028331004

refers to:

number of axles = 3
first axle weight = 10
second axle weight = 28
third axle weight = 33
first spacing = 10
second spacing = 4

Now, you have an idea about my file structure, here is my problem: I would like to group these trucks in separate lists, and name the lists in terms of axle spacings. Let's say I am using a boolean type of approach, and if the spacing is less than 6, the boolean is 1, if it is greater than 6, the boolean is 0. To clarify, possible outcomes in a three axle truck becomes:

00 #Both spacings > 6
10 #First spacing < 6, second > 6
01 #First spacing > 6, second < 6
11 #Both spacings < 6

Now, as you see there are not too many outcomes for a 3 axle truck. However, if I have a 12 axle truck, the number of "possible" combinations go haywire. The thing is, in reality you would not see all "possible" combinations of axle spacings in a 12 axle truck. There are certain combinations (I don't know which ones, but to figure it out is my aim) with a number much less than the "possible" number of combinations.

I would like the code to create lists and fill them with the strings that define the properties I mentioned above if only such a combination exists. I thought maybe I should create lists with variable names such as:

truck_0300[]
truck_0301[]
truck_0310[]
truck_0311[]

on the fly. However, from what I read in SF and other sources, this is strongly discouraged. How would you do it using the dictionary concept? I understand that dictionaries are like 2 dimensional arrays, with a key (in my case the keys would be something like truck_0300, truck_0301 etc.) and value pair (again in my case, the values would probably be lists that hold the actual strings that belong to the corresponding truck type), however I could not figure out how to create that dictionary, and populate it with variable keys and values.

Any insight would be welcome! Thanks a bunch!

解决方案

You are definitely correct that it is almost always a bad idea to try and create "dynamic variables" in a scope. Dictionaries usually are the answer to build up a collection of objects over time and reference back to them...

I don't fully understand your application and format, but in general to define and use your dictionary it would look like this:

trucks = {}
trucks['0300'] = ['a']
trucks['0300'].append('c')
trucks['0300'].extend(['c','d'])

aTruck = trucks['0300']

Now since every one of these should be a list of your strings, you might just want to use a defaultdict, and tell it to use a list as default value for non existant keys:

from collections import defaultdict

trucks = defaultdict(list)
trucks['0300']
# []

Note that even though it was a brand new dict that contained no entries, the 'truck_0300' key still return a new list. This means you don't have to check for the key. Just append:

trucks = defaultdict(list)
trucks['0300'].append('a')

A defaultdict is probably what you want, since you do not have to pre-define keys at all. It is there when you are ready for it.

Getting key for the max value

From your comments, here is an example of how to get the key with the max value of a dictionary. It is pretty easy, as you just use max and define how it should determine the key to use for the comparisons:

d = {'a':10, 'b':5, 'c':50}
print max(d.iteritems(), key=lambda (k,v): v)
# ('c', 50)
d['c'] = 1
print max(d.iteritems(), key=lambda (k,v): v)
# ('a', 10)

All you have to do is define how to produce a comparison key. In this case I just tell it to take the value as the key. For really simply key functions like this where you are just telling it to pull an index or attribute from the object, you can make it more efficient by using the operator module so that the key function is in C and not in python as a lambda:

from operator import itemgetter
...
print max(d.iteritems(), key=itemgetter(1))
#('c', 50)

itemgetter creates a new callable that will pull the second item from the tuple that is passed in by the loop.

Now assume each value is actually a list (similar to your structure). We will make it a list of numbers, and you want to find the key which has the list with the largest total:

d = {'a': range(1,5), 'b': range(2,4), 'c': range(5,7)}
print max(d.iteritems(), key=lambda (k,v): sum(v))
# ('c', [5, 6])

这篇关于在Python中使用字典而不是动态变量名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆