Получение значения по умолчанию для индекса вне диапазона в Python

a=['123','2',4]
b=a[4] or 'sss'
print b

Я хочу получить значение по умолчанию, когда индекс списка вне диапазона (здесь: 'sss').

Как я могу это сделать?

Ответ 1

В духе Питона "просить прощения, а не разрешения", здесь один из способов:

try:
    b = a[4]
except IndexError:
    b = 'sss'

Ответ 2

В не-питонском духе "просить разрешения, а не прощения", здесь другой способ:

b = a[4] if len(a) > 4 else 'sss'

Ответ 3

В питонском духе прекрасного лучше, чем уродливый

Метод кодового гольфа, используя срез и распаковку

b=a[4:4+1] or 'sss'

Ничья, чем функция обертки или try-catch IMHO, но запугивающая для начинающих. Лично я считаю, что распаковка набора будет более сексуальной, чем список [#]

с использованием разрезания без распаковки:

b,=a[4:5] or ['sss']  

или, если вам нужно делать это часто, и не прочь сделать словарь

d = dict(enumerate(a))
b=d.get(4,'sss')

Ответ 4

Вы можете создать свой собственный класс list:

class MyList(list):
    def get(self, index, default=None):
        return self[index] if len(self) > index else default

Вы можете использовать его следующим образом:

>>> l = MyList(['a', 'b', 'c'])
>>> l.get(1)
'b'
>>> l.get(9, 'no')
'no'

Ответ 5

другой способ:

b = (a[4:]+['sss'])[0]

Ответ 6

Вы также можете определить небольшую вспомогательную функцию для этих случаев:

def default(x, e, y):
    try:
        return x()
    except e:
        return y

Возвращает возвращаемое значение функции x, если оно не вызвало исключение типа e; в этом случае он возвращает значение y. Использование:

b = default(lambda: a[4], IndexError, 'sss')

Изменить. Заблокировано только одно указанное исключение.

Предложения по улучшению по-прежнему приветствуются!

Ответ 7

try:
    b = a[4]
except IndexError:
    b = 'sss'

Более чистый способ (работает только если вы используете dict):

b = a.get(4,"sss") # exact same thing as above

Здесь вам может понравиться другой способ (опять же, только для dicts):

b = a.setdefault(4,"sss") # if a[4] exists, returns that, otherwise sets a[4] to "sss" and returns "sss"

Ответ 8

Im все для запроса разрешения (т.е. мне не нравится метод try... except). Однако при его инкапсулировании в методе код становится намного чище:

def get_at(array, index, default):
    if index < 0: index += len(array)
    if index < 0: raise IndexError('list index out of range')
    return array[index] if index < len(a) else default

b = get_at(a, 4, 'sss')

Ответ 9

Для обычного случая, когда вы хотите первый элемент, вы можете сделать

next(iter([1, 2, 3]), None)

Я использую это, чтобы "развернуть" список, возможно, после его фильтрации.

next((x for x in [1, 3, 5] if x % 2 == 0), None)

или

cur.execute("SELECT field FROM table")
next(cur.fetchone(), None)

Ответ 10

Использование try/catch?

try:
    b=a[4]
except IndexError:
    b='sss'

Ответ 11

Поскольку это верхний хит Google, вероятно, стоит также упомянуть, что стандартный пакет "коллекции" имеет "defaultdict", который обеспечивает более гибкое решение этой проблемы.

Вы можете делать аккуратные вещи, например:

twodee = collections.defaultdict(dict)
twodee["the horizontal"]["the vertical"] = "we control"

Подробнее: http://docs.python.org/2/library/collections.html

Ответ 12

Если вы ищете удобный способ получения значений по умолчанию для оператора индекса, я нашел следующее полезное:

Если вы переопределите operator.getitem из модуля оператора, чтобы добавить необязательный параметр по умолчанию, вы получите идентичное поведение с оригиналом при сохранении обратной совместимости.

def getitem(iterable, index, default=None):
  import operator
  try:
    return operator.getitem(iterable, index)
  except IndexError:
    return default

Ответ 13

Если вы ищете быстрый взлом для уменьшения длины кода по-символу, вы можете попробовать это.

a=['123','2',4]
a.append('sss') #Default value
n=5 #Index you want to access
max_index=len(a)-1
b=a[min(max_index, n)]
print(b)

Но этот трюк полезен только тогда, когда вы больше не хотите вносить изменения в список