Список Python, проиндексированный по кортежам - PullRequest
3 голосов
/ 20 января 2010

Я - пользователь Matlab, которому нужно для некоторых целей использовать Python, я был бы очень признателен, если бы кто-нибудь помог мне с синтаксисом Python:

(1) Правда ли, что списки могут быть проиндексированыкортежи в Python?Если да, то как мне это сделать?Например, я хотел бы использовать это для представления матрицы данных.

(2) Предполагая, что я могу использовать список, проиндексированный кортежами, скажем, data [(row, col)], как мне удалитьцелый столбец?Я знаю, что в Matlab я могу сделать что-то вроде

 new_data = [data(:,1:x-1) data(:,x+1:end)];

, если я хочу удалить столбец x из данных.

(3) Как я могу легко подсчитать количество неотрицательных элементовв каждом ряду.Например, в Matlab я могу сделать что-то вроде этого:

 sum(data>=0,1)

это даст мне вектор-столбец, который представляет количество неотрицательных записей в каждой строке.

Спасибомного!

Ответы [ 7 ]

8 голосов
/ 20 января 2010

Вы должны посмотреть на numpy , это сделано именно для такого рода вещей.

3 голосов
/ 20 января 2010
  1. Нет, но дикты могут.
  2. Звучит так, как будто вы хотите "2d массив", тип матрицы или что-то еще.Вы уже смотрели на numpy ?
  3. Зависит от того, что вы выбираете из # 2, но Python имеет sum и другие функции, которые работают непосредственно с итерациями.Посмотрите на gen-exprs (выражения генератора) и составьте список понятий.Например:
row_count_of_non_neg = sum(1 for n in row if n >= 0)
# or:
row_count_of_non_neg = sum(n >= 0 for n in row)
# "abusing" True == 1 and False == 0
2 голосов
/ 20 января 2010

Я согласен со всеми. Используйте Numpy / Scipy. Но вот конкретные ответы на ваши вопросы.

  1. Да. И индекс может быть встроенным списком или массивом Numpy. Предположим, x = scipy.array([10, 11, 12, 13]) и y = scipy.array([0, 2]). Затем x[[0, 2]] и x[y] оба возвращают одно и то же.

  2. new_data = scipy.delete(data, x, axis=0)

  3. (data>=0).sum(axis=1)

Осторожно: пример 2 иллюстрирует типичную ловушку с Numpy / Scipy. Как показано в примере 3, свойство axis обычно устанавливается в 0 для работы по первому измерению массива, 1 для работы по второму измерению и так далее. Но некоторые команды, такие как delete, на самом деле изменяют порядок измерений, как показано в примере 2. Вы знаете, мажор строки против майора столбца.

2 голосов
/ 20 января 2010

Вот пример того, как легко создать массив (матрицу) в numpy:

>>> import numpy
>>> a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])

вот как это отображается

>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

и как получить строку или столбец:

>>> a[0,:]
array([1, 2, 3])
>>> a[:,0]
array([1, 4, 7])

Надеюсь, синтаксис понятен из примера! Numpy довольно мощный.

1 голос
/ 11 августа 2017

Функциональность списка можно расширить, чтобы разрешить индексирование с помощью кортежей, перегрузив методы встроенного списка __getitem__ и __setitem__. Попробуйте следующий код:

class my_list(list):
    def __getitem__(self, key):
        if isinstance(key, tuple) and len(key) > 0:
            temp = []
            for k in key: temp.append(list.__getitem__(self, k))
            return temp
        else:
            return list.__getitem__(self, key)

    def __setitem__(self, key, data):
        if isinstance(key, tuple) and len(key) > 0:
            for k in key: list.__setitem__(self, k, data)
        else:
            list.__setitem__(self, key, data)


if __name__ == '__main__':
   L = my_list([1, 2, 3, 4, 5])
   T = (1,3)
   print(L[T]) 
0 голосов
/ 20 января 2010

Нет, это не тот случай, когда список может быть проиндексирован чем угодно, кроме целого числа.Словарь, однако, другой случай.Словарь - это хеш-таблица, состоящая из пар ключ-значение.Ключи должны быть уникальными и неизменными.Значением могут быть объекты любого типа, включая целые числа, кортежи, списки или другие словари.Для вашего примера, кортежи могут служить ключами, так как они являются неизменяемыми.Списки, с другой стороны, не являются и, следовательно, не могут быть словарными ключами.

Некоторые из возможностей, о которых вы спрашивали, могут быть реализованы как комбинация словаря и списочных представлений.Другим потребовалось бы создать подклассы словаря и добавить методы для реализации желаемой функциональности.

0 голосов
/ 20 января 2010

(1) Я не думаю, что вы можете использовать кортеж в качестве индекса списка Python. Вы можете использовать список из списка (например, a [i] [j]), но, похоже, это не ваша точка зрения. Вы можете использовать словарь, ключ которого является кортежем.

d = { (1,1):1, (2,1):2  ... } 

(2) Если вы не возражаете против производительности,

map( lambda x: d.remove(x) if x[1] = col_number, d.keys() )

(3) Вы также можете использовать фильтр, чтобы сделать это.

sum(
map( lambda x:x[1], filter(lambda x,y: x[1] == row_num and y > 0, d.items()))
)
...