【问题标题】:How to generate variables automatically using values from a list elements using for-loop?如何使用for循环使用列表元素中的值自动生成变量?
【发布时间】:2017-06-03 00:21:48
【问题描述】:

假设我想使用 forloop 自动为大标题行生成索引,以防止为每个标题编写索引。

在一个文件中,我说了一个带有很多水果名称的标题。每列都有一个数据,我必须使用索引访问这些数据以进行下游解析。我不想为每个水果名称准备索引,而是想运行一个 forloop 来即时创建索引值以节省时间。

data = 

      apple                     banana              orange
      genus:x,species:b    genus:x,species:b     genus:x,species:b
      genus:x,species:b    genus:x,species:b     genus:x,species:b
      variety:gala,pinklady,...  variety:wild,hybrid...   variety:florida,venz,
      flavors:tangy,tart,sweet..
      global_consumption:....
      pricePerUnit:...
      seedstocks:.....
      insect_resistance:.....
      producer:....


# first I convert the header into list like this:

for lines in data:
    if 'apple' in lines:
        fruits = lines.split('\t')
        # this will give me header as list:
        # ['apple', 'banana', 'orange']

        # then create the index as:           
        for x in fruits:
            str(x) + '_idx' = fruits.index(x)  
            # this is where the problem is for me .. !??   
            # .. because this is not valid python method
            print(x)

            # if made possible, new variable are created as
            apple_idx = 0, banana_idx = 1 ... so on

# Now, start mining your data for interested fruits
     data = lines.split('\t')
     apple_values = data[apple_idx]
     for values in apple_values:
          do something ......

     same for others. I also need to do several other things.

Make sense?? 

如何才能做到这一点?以非常简单的方式。

后期编辑:阅读大量内容后,我意识到可以使用 bash 中另一个变量的 value(string) 创建 variable_name

how to use a variable's value as other variable's name in bash

https://unix.stackexchange.com/questions/98419/creating-variable-using-variable-value-as-part-of-new-variable-name

但是,正如我所想的那样,在 python 中是不可能的。我的直觉是,可以在 python 编程语言中准备这种方法(如果被黑或作者决定),但也有可能是 python 的作者想到并知道可能的危险或使用这种方法。

  • 危险在于您总是希望variable_name 在编写的python 脚本中可见。准备一个动态的 variable_names 会很好,但是如果出现任何问题,它可能会在回溯时导致问题。
  • 由于从未输入变量名,因此如果出现任何问题(尤其是在大型程序中),跟踪和调试将是一场噩梦,比如当 variable_value 类似于 2BetaTheta*ping^pong 这不是有效的变量名。这是我的想法。 请其他人加入,为什么 python 中没有引入此功能?
  • Dict 方法解决了这个问题,因为我们有 variable_name 的来源记录,但变量名有效与无效的问题仍然没有消失。

我将使用dict method 获取一些提供的答案,看看我是否可以找到一种非常简单全面的方法来实现这一点。

谢谢大家!

【问题讨论】:

  • 这是XY problem- 意思是,您是在询问您认为什么是您要解决的问题的好解决方案,而不是询问您要解决的实际问题。没有理由以您尝试的方式命名许多具有不同名称的变量。您真正想要完成的事情是什么?
  • 我想自动创建一个变量,其中变量名是 (x-name + '_idx'),它的值是它在该列表中的位置。
  • 也许你可以创建一本字典?然后你可以像dict["apple"]一样访问它,你就得到了对应的索引。
  • 好吧,但是你为什么要这样做?你想完成什么?
  • 我想,我解释了我想要完成的事情。我正在尝试创建新变量及其值,因为它在列表中的位置,所以当我有 100 行时,我不必为每个变量键入索引。有道理。

标签: python list for-loop indexing


【解决方案1】:

希望下面的代码能够为您提供一些关于前进方式的想法。实际上有比这些更好的方法来做这些事情,但对于初学者来说,最好先学习基础知识。请注意:下面的代码并没有什么真正的错误,但如果我们使用一些更高级的概念,它可能会更短,甚至更有用。

# get the headers from the first line out of the data
# this won't work if the headers are not on the first line
fruits = data[0].split('\t')

# now you have this list, as before
>>> ['apple', 'banana', 'orange']

# make a dictionary that will hold a data list
# for each fruit; these lists will be empty to start
# each fruit's list will hold the data appearing on 
# each line in the data file under each header
data_dict = dict()
for fruit in data_dict:
    data_dict[fruit] = [] # an empty list

# now you have a dictionary that looks like this
>>> {'apple': [], 'banana': [], 'orange': []}

# you can access the (now empty) lists this way
>>> data_dict['apple']
[]

# now use a for loop to go through the data, but skip the 
# first line which you already handled
for lines in data[1:]:
    values = lines.split('\t')
    # append the values to the end of the list for each 
    # fruit. use enumerate so you know the index number
    for idx,fruit in enumerate(fruits):
        data_dict[fruit].append(values[idx])

# now you have the data dictionary that looks like this
>>> {'apple': ['genus:x,species:b', 'genus:x,species:b'], 
     'banana': ['genus:x,species:b', 'genus:x,species:b'], 
     'orange': ['genus:x,species:b', 'genus:x,species:b']}

print("<<here's some interesting data about apples>>")
# Mine the data_dict for interesting fruits this way
data_list = fruits['apple']
for data_line in data_list:
    genus_and_species = data_line.split(',')
    genus = genus_and_species[0].split(':')[1] 
    species = genus_and_species[1].split(':')[1] 
    print("\tGenus: ",genus,"\tSpecies: ",species)

如果您想查看所有水果(按照之前的原始顺序),您可以这样做:

for fruit in fruits:
    data_list = data_dict[fruit]
    for data_line in data_list:
        print(data_line)

如果你不关心订单(dicts 没有订单*),你可以忘记你的水果列表,只循环数据字典本身:

for fruit in data_dict:
    print(fruit)

或获取值(数据列表),使用values(Python 2.7 中为viewvalues):

for data_list in data_dict.values():
    print(data_list)

或获取键(水果)和值,使用items(Python 2.7 中的viewitems):

for fruit,data_list in data_dict.items():
    print(data_list)

提示:如果你想改变(改变)字典,不要使用for fruit in data_dict:。相反,您需要确保使用valuesitemskeys(Python 2.7 中的viewkeys)方法。如果你不这样做,你会遇到问题:

for fruit in data_dict.keys():
    # remove it
    data_dict.pop(fruit)

* 快速说明:dicts 已经发生了一些变化,你很可能会假设他们会在即将到来的 Python 的下一版本(3.7)中真正记住他们的顺序。

【讨论】:

    【解决方案2】:

    编辑:现在问题已被编辑,如果有时间,我稍后会提供更有用的答案。

    我不完全理解您实际上想要做什么,但这里有一些可能会有所帮助的事情。

    要认识到的是,您已经有一个对象,其中包含您所需要的所有信息:一个包含所有对象名称的列表。就其本质而言,您的姓名列表中已经包含索引。数据存在;它在那里。您需要做的是学习以正确的方式访问这些信息。

    您可能需要的是enumerate function。此函数生成一个包含列表索引和列表内容的两个元组(这是一对对象):

    for idx,fruit in enumerate(fruits): 
        print(fruit+'_idx: ', idx)
    

    没有理由将这些索引存储在其他数据结构中;它们已经在您的列表中。

    如果您坚持要通过某个名称(字符串)访问某个任意值,您应该使用字典或dict

    fruit_dict = dict()
    fruit_dict['apple'] = 1
    

    但是,由于您在 index 值之后,这样做似乎有点奇怪,因为 dict 本质上是无序的。正如我所说,您已经知道列表中的索引。再次存储带有名称的索引很可能没有什么意义,尽管在某些情况下您可能想要这样做。

    【讨论】:

      【解决方案3】:

      内置函数execeval 与此处相关。

      来自Python documentation

      • eval: "表达式参数被解析并评估为 Python 表达式"
      • exec: "该函数支持动态执行Python代码"

      真的,你的问题只需要exec,如下:

      for fruit in fruits: exec('{0}_idx = fruits.index("{0}")'.format(fruit))

      (请注意,我们需要在第二个 {} 中加上引号,否则 Python 会认为您正在尝试获取某个名为 apple 的变量的索引,而不是将字符串 'apple' 传递给它。

      如果您现在在控制台中输入apple_idx(例如),它应该返回0

      【讨论】:

      • 为显然不知道自己在做什么的人提供食物,但解决方案最终会将他们引向他们不应该去的方向,这对他们没有帮助,即使他们认为这是. (否决)
      • 嗨瑞克,我认为这个问题有解决方案。我的 python 不是很强大,无法以正确的方式工作,但总有办法。我理解 X/Y 问题。但是,这不是 XY 问题。应该有办法的。
      • 我告诉你:这是一个 XY 问题。我相信你相信它不是,但它肯定是。
      • 我要多读一些。这是我的一个小代表,我希望你是对的。不管我会找到什么答案,这将是另一个启示。哈哈。至少非常感谢你的推挤。
      猜你喜欢
      • 1970-01-01
      • 2017-08-16
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多