【问题标题】:slicing subset of list in a dict: how to turn index to integer?在字典中切片列表的子集:如何将索引转换为整数?
【发布时间】:2021-08-19 10:17:36
【问题描述】:

从用户输入中,您可以获得一个表达式,该表达式指示您想要从 dict 中获得哪些元素:

key[0]
key[0:2]
key[-1]

key 是字典中的键。 dict 中的值存储为列表。因此,如果用户输入key[0],则应该返回值列表中的第一个元素。

现在,我通过使用:

input = ['key[0]']
key = input[0].split('[')[0]
index = self[0].split('[')[1].replace(']', '')
return dict[key][int(index)]

有点难看,我得承认,但它适用于正常整数。问题是在尝试获取像key[0:2] 这样的子集时,因为显然0:2 不是整数。 无论如何,我怎样才能让它工作?有没有更有效的方法来做到这一点?

PS:我也试过eval(index),但同样的问题......

【问题讨论】:

  • 编写一个函数来解析字符串输入并根据需要进行处理。确定它是整数还是切片语句,然后进行相应处理。我发现允许用户提供字符串输入来访问我的数据很笨拙,所以无论如何我都不会这样做。
  • @PatrickArtner 我不确定我是否正确理解了这一点,但它甚至会如何使用 slice 语句呢?它不会仍然是一个字符串并带我回到最初的问题吗?

标签: python python-3.x list dictionary subset


【解决方案1】:

您需要创建一个函数来处理您的用户输入并处理(或失败)所有可能的用户输入(因此我不愿意这样做 - 用户总是做愚蠢的事情 ):

def check_and_return(d, inp):
    """Not usable in production - handles not all cases. 
    Does not check if d is a dict. You are warned."""
    inp = str(inp) # make sure it is a string

    if not inp.strip():
        raise AttributeError("bad input")

    # not handled: input of "justakeynobracket"
    key, arg = inp.split("[", 1)  # may raise on invalid input - not handled

    def intOrNoneOrThrow(s):
        return int(s) if s.strip() else None

    if key in d:
        arg = arg.strip("]").split(":")
        lenArg = len(arg)
        if lenArg == 1:
            arg = int(arg[0])  # may raise ValueError
            return d[key][arg]  # retunrs 1 value
        elif 1 < lenArg < 4:
            # may raise ValueError
            start = intOrNoneOrThrow (arg[0])
            stop = intOrNoneOrThrow (arg[1])  
            # handle steps
            step = None
            if lenArg == 3:
                step = intOrNoneOrThrow(arg[2])
                
            return d[key][slice(start,stop,step)]  # returns a list

    else:
        raise KeyError(f"Not a key: '{key}'")

使用/测试:

d = {"key":[1,2,3,4,5,6,7,8]}

for i in ['key[:5:-1]','key','key[1]','key[1:4]','not[0]','key[-1:-7:-2]','']:
    try:
        print(check_and_return(d, i))
    except Exception as e:
        print(e)

输出:

[8, 7]
not enough values to unpack (expected 2, got 1)
2
[2, 3, 4]
"Not a key: 'not'"
[8, 6, 4]
bad input

【讨论】:

  • 例如 key[::-1] 失败,因为您的默认设置不正确。可以用return d[key][slice(*(int(i) if i.strip() else None for i in arg))] 完成整个elif 部分
  • @KellyBundy 感谢您指出这一点。您的一个衬里很好,我出于调试目的对其进行了不同的调整/修复 - 无法在一个衬里内设置断点,并且 """ 不能在生产中使用 - 不能处理所有情况。不检查 d 是否是一个字典。警告您。""" 仍然适用。
  • 嗨!谢谢你的回答!我一直在寻找不那么冗长的东西,但是一旦我的代码进一步进步,这将很有帮助。非常感谢您的帮助:)
猜你喜欢
  • 2012-06-14
  • 2016-11-02
  • 2014-12-09
  • 2019-02-05
  • 2022-10-06
  • 1970-01-01
  • 2021-08-17
  • 2020-08-07
  • 2016-07-27
相关资源
最近更新 更多