Python нарезка списка кортежей и преобразование значений в целые числа - путаница в том, почему это возможно с массивами numpy, но без списка кортежей - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь вырезать первое и последнее значения из списка, а затем преобразовать эти значения в целые числа. Я нашел решение, но меня смущает, почему это решение работает, и мне интересно, есть ли более простой способ, поскольку он кажется довольно не элегантным.

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

Вопрос 1 : существует ли одношаговое решение для вырезания одного значения из списка списка?
Вопрос 2 : Почему смешанный список (некоторые значения являются числами и некоторые буквы) не состоит из целых чисел и строк против всех кортежей? * Массивы numpy или другой подход разрешают смешанные списки? Извините, если я не использую правильную терминологию ...

Список нарезки списка - метод понимания списка

#Say I have a list of a list with mixed numbers and letters.

>>>a=[('1', 'T', ''), ('2', 'R', 'S'), ('3', 'E', 'S'), ('4', 'T', 'S')]
#list comprehension slice 1D
>>>b=[list[0:1] for list in a]
>>> print(b):
[('1',), ('2',), ('3',), ('4',)]

>>> start=(b[0:1])
>>> print(start):
[('1',)]
>>> end=b[len(b)-1:len(b)]
>>> print(end)
[('4',)]

Список нарезки списка - numpy метод массива #Say I есть список из списка со смешанными числами и буквами.

>>>a=[('1', 'T', ''), ('2', 'R', 'S'), ('3', 'E', 'S'), ('4', 'T', 'S')]
>>> b_array=numpy.array(a)
>>> print(b_array)
array([['1', 'T', ''],
       ['2', 'R', 'S'],
       ['3', 'E', 'S'],
       ['4', 'T', 'S']], dtype='<U1')

>>>start_array = b_array[0:1,0:1]
>>>print(start_array)
array([['1']], dtype='<U1')

>>>end_array = b_array[len(b_array)-1:len(b_array),0:1]
>>>print(end_array)
array([['4']], dtype='<U1')

Оба подхода работают, но меня смущает то, что они ведут себя по-разному, если я вызываю для них int (). Понимание списка Если я использую понимание списка, чтобы попробовать чтобы превратить все b в целые числа

>>>b_int= [int(i) for i in b] 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
TypeError: int() argument must be a string, a bytes-like object or a number, not 'tuple'

или превратить start или end в целые числа

>>>start=int(b[0:1])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

Я получаю похожие ошибки. Но вторая говорит, что это список, хотя это одно значение в списке 1x1.

В качестве альтернативы, если я делаю то же самое для start_array, это нормально

>>>start_array=int(b_array[0:1,0:1])
>>>print(start_array)
1

Итак, в итоге, Я нашел рабочее решение, но оно кажется неуклюжим, и я не понимаю, почему это работает в numpy массивах, а не в списке списков.

Вопрос 3 : Почему я могу преобразовать значения в массивах numpy в целые числа, а не в списки списков?
Вопрос 4 : Есть ли чище или проще способ сделать это в python?

Спасибо

edit: Итак, мое недоразумение заключалось в том, что я думал, что имею дело со списком списков. Я не был, вместо этого я работал со списком кортежей. Я изменил название, но не тело. Вторая проблема заключалась в том, что я выполнял индексацию срезов, а не скалярную индексацию. Это привело к тому, что мои элементы не были удалены из списка. Для решений я мог бы либо:

#List comprehension to reduce dimensionality
a=[('1', 'T', ''), ('2', 'R', 'S'), ('3', 'E', 'S'), ('4', 'T','S')]
b=[x[0] for x in a]
start=int(b[0])
end=int(b[-1])

#Directly index with a scalar
start=int(b[0][0])
end=int(b[-1][0])

Я буду непосредственно индексировать со скаляром, поскольку это проще. Хотя, если бы я хотел проиндексировать несколько списков чисел, было бы более полезным.

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Вы индексируете слайсами, которые возвращают список (или кортеж). Индексирование с помощью числа (скаляр) убирает элемент из списка (или кортеж):

In [8]: a=[('1', 'T', ''), ('2', 'R', 'S'), ('3', 'E', 'S'), ('4', 'T', 'S')]                  
In [9]: b=[x[0] for x in a]                                                                    
In [10]: b                                                                                     
Out[10]: ['1', '2', '3', '4']
In [11]: b[0]                                                                                  
Out[11]: '1'
In [12]: int(b[0])                                                                             
Out[12]: 1
In [13]: b[-1]                                                                                 
Out[13]: '4'    # int(b[-1]) works

Аналогично массиву. Индекс среза сохраняет размерность, скалярный индекс уменьшает размерность (и):

In [14]: arr = np.array(a)                                                                     
In [15]: arr                                                                                   
Out[15]: 
array([['1', 'T', ''],
       ['2', 'R', 'S'],
       ['3', 'E', 'S'],
       ['4', 'T', 'S']], dtype='<U1')
In [16]: arr[0,:]                                                                              
Out[16]: array(['1', 'T', ''], dtype='<U1')
In [17]: arr[:,0]                                                                              
Out[17]: array(['1', '2', '3', '4'], dtype='<U1')

Обратите внимание на arr dtype; мы можем изменить это на int:

In [18]: arr[:,0].astype(int)                                                                  
Out[18]: array([1, 2, 3, 4])

Как правило, вы не хотите использовать int(b_array[0:1,0:1]). Он работает для одного числа, но не для нескольких:

In [19]: int(arr[:,0])                                                                         
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-19-9c2041fff718> in <module>
----> 1 int(arr[:,0])

TypeError: only size-1 arrays can be converted to Python scalars

Индексирование list является Python оригиналом. numpy расширил это индексирование. Расширения numpy не были перенесены обратно на list.


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

In [26]: [x for x in a[:2]]                                                                    
Out[26]: [('1', 'T', ''), ('2', 'R', 'S')]

эквивалентно индексированию с помощью скаляра:

In [27]: [a[i] for i in range(2)]                                                              
Out[27]: [('1', 'T', ''), ('2', 'R', 'S')]

Индексирование с фрагментом 'обертки' каждый x в списке:

In [28]: [a[i:i+1] for i in range(2)]                                                          
Out[28]: [[('1', 'T', '')], [('2', 'R', 'S')]]

В b=[list[0:1] for list in a], list - это один из кортежей в a. Это не slice из a.

In [29]: a[0][0:1]         # slice of a tuple from a list                                                                             
Out[29]: ('1',)
In [30]: a[0:1][0:1]       # slice of a slice                                      
Out[30]: [('1', 'T', '')]
In [31]: a[0][0]           # element of a tuple from the list                                                  
Out[31]: '1'
1 голос
/ 14 февраля 2020

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

a = [('1', 'T', ''), ('2', 'R', 'S'), ('3', 'E', 'S'), ('4', 'T', 'S')]

firstNum = int(a[0][0])
lastNum = int(a[-1][0])

print(firstNum)
print(lastNum)

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

...