从Ruby到Python - 是否有相当于“尝试”的东西?

时间:2017-09-24 12:30:19

标签: python list dictionary

在Ruby(实际上是在Rails上),我有try函数:

[].try(:[], 1) # => nil
[10].try(:[], 1) # => nil
[10, 20].try(:[], 1) # => 20
[10, 20, 30].try(:[], 1) # => 20

{}.try(:foo) # => nil
{ foo: 'bar' }.try(:foo) # => 'bar'

该功能基本上是一种快捷方式,可以避免if检查位置是否存在 Python中有类似的内容吗?

6 个答案:

答案 0 :(得分:4)

词典:dict.get

您可以使用dict.get

d = {'foo' : 'bar'}

print(d.get('foo'))
'bar'

print(d.get('xxxxx'))
None

您还可以将默认参数传递给get

print(d.get('xxxxx', 'Invalid Key!'))
Invalid Key!

当字典中不存在该键时,将打印出默认值。

列表:自定义try - except阻止

不幸的是,列表的API中没有dict.get等效项,因此您需要自己实现一个。值得庆幸的是,您可以扩展list类并覆盖__getitem__以完全执行此操作。

class MyList(list):
    def __getitem__(self, idx, default='oops'):
        try:
            return super().__getitem__(idx)
        except IndexError:
            return default

l = MyList([10, 20])

l[1]
# 20

l[3]
# 'oops'

答案 1 :(得分:2)

python list对象没有安全.get就像字典一样。

你需要用自己的尝试来捕获它,除了:

try:
    return your_list[index]
except IndexError:
    return default # could be -1 for example

答案 2 :(得分:2)

在Python中不可能有类似try的方法,因为try至关重要地依赖于猴子修补ObjectNilClass,以及它们的Python等价物({{ 1}}和object)不能修补猴子:

NoneType

但是,您可以编写一个行为相似的全局def try_object(self, f, *args, **kwargs): return getattr(self, f)(*args, **kwargs) def try_none(self, f, *args, **kwargs): return None object.try = try_object object.try = try_object # ^ # SyntaxError: invalid syntax NoneType.try = try_none # ^ # SyntaxError: invalid syntax 函数:

try

答案 3 :(得分:1)

使用dict'你可以使用d.get('foo'),如果密钥不存在则不返回任何内容。您还可以指定defualt值d.get('foo', 'bar'),如果密钥bar不在dict中,则返回foo

对于列表,没有这种明显的方式。您可以定义一个简单的函数,

def check_item(list_obj, item):
    try:
        return list_obj[item]
    except IndexError:
        pass

如果存在,将返回值,如果不存在,则返回任何值。然后简单地称之为value = check_item(list_item, item_to_look)

更高级的选项是将list类子类化,并将__getitem__方法覆盖为具有与上述类似逻辑的函数。 (它需要一些额外的修改来处理slice个对象等。)

答案 4 :(得分:0)

在python中,你必须遵守这个咒语" 比获得许可更容易请求宽恕"。

但是,对于列表,您可以像这样写一个支票,使列表成为一个以索引为键的dict。

>>>en = enumerate([10, 20])
>>>dct = dict(en)
>>>dct.get(2)
None
>>>dct.get(1)
20

答案 5 :(得分:0)

结合解决方案

def safe_get(data, key):
    if isinstance(data, (list, set, tuple)):
        return dict(enumerate(data)).get(key)
    elif isinstance(data, dict):
        return (data).get(key)
    else:
        return None

print safe_get([], 1)
None
print safe_get([10], 1)
None
print safe_get([10, 20], 1)
20
print safe_get([10, 20, 30], 1)
20
print safe_get({}, 'foo')
None
print safe_get({ 'foo': 'bar' }, 'foo')
bar