Счетчик в диапазоне () не распознается как целое число - PullRequest
5 голосов
/ 26 марта 2019

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

def get_vote_fraction(cl_count, ag_vector):
    v_f_vector = [[0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0, 0]]
    for b in range(0, len(v_f_vector)):
        for c in range(0, len(v_f_vector[b])):
            v_f_vector[b][c] = f"{(ag_vector[b][c] / cl_count): .2F}"
    return v_f_vector


aggregated_vector = [[0, 8, 0, 6], [0, 1, 0, 0, 0, 0, 9, 0], [0, 0, 10, 0], [0, 10, 0, 0, 0]]
class_count = 10
vote_fraction = get_vote_fraction(class_count, aggregated_vector)
print(vote_fraction)

Как и ожидалось, результат будет [['0,00', '0,80', '0,00', '0,60'], ['0,00', '0,10',' 0,00 ',' 0,00 ',' 0,00 ',' 0,00 ',' 0,90 ',' 0,00 '], [' 0,00 ',' 0,00 ',' 1,00 ',' 0,00 '], [' 0,00 ','1,00', '0,00', '0,00', '0,00']]

Я получаю предупреждение, что c в v_f_vector [b] [c] может быть непредвиденного типа (типов) (int, str)который говорит, что c недостаточно определен как целое число.Я не решаюсь поднять проблему с PyCharm, поскольку я могу упустить что-то простое.Кто-нибудь видит, чего мне не хватает?

Ответы [ 3 ]

2 голосов
/ 27 марта 2019

Относительно PyCharm предупреждение (о чем вопрос)

Хотя индекс 2 nd ( c ) подсвечивается, заставляя пользователей думать, что это - это проблема, вообще не в этом дело .

Как правило, списки однородные контейнеры, что означает, что они содержат элементы одного типа.
PyCharm оценивается v_f_vector как список списков int s (и, следовательно, v_f_vector[b][c] как int ).Попытка присвоить ей строку может нарушить однородность списка, а значит, и предупреждение.
Попробуйте присвоить ему фиктивные значения (например, 0.01f, (), [], ...), и текст предупреждения изменится, как показано на рисунке ниже:

Img0

В качестве быстрого (и грязного) обходного пути, если списки будут содержать строки, вы можете сделать что-то вроде:

v_f_vector = [["", "", "", ""], ["", "", "", "", "", "", "", ""], ["", "", "", ""], ["", "", "", "", ""]]

Относительно кода, который приводит к этому

Объявление списка с определенным содержимым, а затем возвращение и изменение этого содержимого (на основе другого (аналогичного структурного) списка) нелогично.

Ваша (конечная) цель может быть достигнута в одной строке кода (самая Python ic форма), состоящей из списка понимания (отметьте [Python 3]: список пониманий ).Так как ваш уровень вложенности в списке равен 2, то будет понятно и следующее:

>>> aggregated_vector = [[0, 8, 0, 6], [0, 1, 0, 0, 0, 0, 9, 0], [0, 0, 10, 0], [0, 10, 0, 0, 0]]
>>> class_count = 10
>>>
>>> vote_fraction = [[f"{(item1 / class_count): .2F}" for item1 in item0] for item0 in aggregated_vector]
>>> print(vote_fraction)
[[' 0.00', ' 0.80', ' 0.00', ' 0.60'], [' 0.00', ' 0.10', ' 0.00', ' 0.00', ' 0.00', ' 0.00', ' 0.90', ' 0.00'], [' 0.00', ' 0.00', ' 1.00', ' 0.00'], [' 0.00', ' 1.00', ' 0.00', ' 0.00', ' 0.00']]
>>>
>>> # Or, if you REALLY need to have a function
...
>>> def get_vote_fraction(cl_count, ag_vector):
...     return [[f"{(item1 / cl_count): .2F}" for item1 in item0] for item0 in ag_vector]
...
>>>
>>> print(get_vote_fraction(class_count, aggregated_vector))
[[' 0.00', ' 0.80', ' 0.00', ' 0.60'], [' 0.00', ' 0.10', ' 0.00', ' 0.00', ' 0.00', ' 0.00', ' 0.90', ' 0.00'], [' 0.00', ' 0.00', ' 1.00', ' 0.00'], [' 0.00', ' 1.00', ' 0.00', ' 0.00', ' 0.00']]

Примечание : ваш код также может быть адаптирован, но я бы предложилперейти с рекомендуемого варианта (ов).

1 голос
/ 27 марта 2019

Я думаю, что предупреждение исходит из того факта, что вы заменяете целочисленные значения строками. Когда я пытался создать экземпляр v_f_vector с '0' вместо 0, PyCharm не показывал никаких предупреждений:

v_f_vector = [['0', '0', '0', '0'], ['0', '0', '0', '0', '0', '0', '0', '0'], ['0', '0', '0', '0'], ['0', '0', '0', '0', '0']]

Однако это может быть не лучшим способом решить проблему. Я бы предложил такой рефакторинг вашего кода:

def get_vote_fraction(cl_count, ag_vector):
    v_f_vector = []
    for b in range(0, len(ag_vector)):
        v_f_vector.append([])
        for c in range(0, len(ag_vector[b])):
            v_f_vector[b].append(f"{(ag_vector[b][c] / cl_count): .2F}")
    return v_f_vector


aggregated_vector = [[0, 8, 0, 6], [0, 1, 0, 0, 0, 0, 9, 0], [0, 0, 10, 0], [0, 10, 0, 0, 0]]
class_count = 10
vote_fraction = get_vote_fraction(class_count, aggregated_vector)
print(vote_fraction)

Это позволит вам изменить aggregated_vector, не отражая эти изменения, для экземпляра v_f_vector.

0 голосов
/ 26 марта 2019

Вы должны использовать enumerate()

Пример:

iterable = [1,2,3,4]
for i, v in enumerate(iterable):
    print(i,v)

Ожидаемый результат

0 1
1 2
2 3
3 4

Вместо

for x in range(0, len(iterable)):
    print(x, iterable[x])

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

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

Просто пища для размышлений

Чтобы добавить ясности, скажем, у вас есть 4 вектора, векторы a, b, x и y. Вы можете иметь каждый из соответствующих списков в своем собственном ключе словаря, а затем обращаться к ним по их ключу.

...