[Tutor] Follow-up on my removing elements from lists question.
Mats Wichmann
mats at wichmann.us
Sat Jun 15 14:14:32 EDT 2019
On 6/15/19 3:35 AM, mhysnm1964 at gmail.com wrote:
Data structure:
['123123',[2019-2-18', 'transaction text', 'amount'],
I presume the second opening brace is a typo and was supposed to be a
quote mark?
> The 2nd column where the transaction text I am modifying the content and
> using the end result of the built-up words as the string match as you will
> see in the code. This is all working fine. The last loop in the code I am
> trying to delete the elements in reverse order. This doesn't work. The
> length of the list reduces by 1. When it should have reduced by 42. Is the
> logic wrong? This is in Python 3.6 under windows 10.
There's a lot that looks odd in this code, let me poke at a few:
You _appear_ to be be trying to avoid modifying 'unknown_transactions'
while looping over it, which is admirable if that was the intent:
for e, v in enumerate (unknown_transactions):
if word in unknown_transactions[e][2]:
if not word in transaction:
transaction[word] = unknown_transactions
else:
transaction[word].append(unknown_transactions)
delete_transactions.append (e)
for del_element in reversed(delete_transactions):
unknown_transactions.pop(del_element)
but that whole sequence is inside another loop over
'unknown_transactions'. Is that intentional? It seem odd to loop over
something inside a loop over that thing.
As a hint, if you want to modify a list while looping you can loop over
a copy of it, like
for s in somelist[:]:
or if you don't like the slice notation,
for s in list(somelist):
you're looping over 'unknown_transactions' here, but you're not using
the loop value 'v' at all in the body. Perhaps that's the thing you
wanted to add to 'transactions'? adding 'unknown_transactions' seems
strange.
usually if you're using multiple levels of indexing you're not
necessarily wrong, but leaving yourself (or others) hard to read code.
In the past I've written such things and a year later I come back to
look and wonder about the magic in something like [e][2]:
if word in unknown_transactions[e][2]:
You can unpack each transaction list instead to avoid indexing it, and
if you are deleting on the spot, you don't need the enumerate value
either. So a possible rewrite could be:
for u in unknown_transactions[:]:
id, date, text, amount = u
if word in text:
if not word in transaction:
transaction[word] = u
else:
transaction[word].append(u)
unknown_transactions.remove(u)
the inner 'if' statement could become a try block as well if you wanted:
try:
transaction[word].append(u)
except KeyError:
transaction[word] = u
And you can save a level of indentation by inverting your early
if-statement, from
if line != '':
whole bunch of code
to
if not line:
continue
whole bunch of code
Just to make things a little more readable.
More information about the Tutor
mailing list