Hello!

a = [(['192.168.0.1'], ['8080']), (['192.168.0.2'], ['4662']), (['192.168.0.3'], ['8080', '4662']), (['192.168.0.4'], ['8080', '4662']), (['192.168.0.5'], ['8080', '4662']), (['192.168.0.6'], ['8080']), (['192.168.0.8'], ['80', '443'])] 

Why it works like this: for key,val in a: d[key[0]] = val

This doesn't work like this: [(d[key[0]] = val) for key,val in a]

  File "<stdin>", line 1 [(d[key[0]] = val) for key,val in a] ^ SyntaxError: invalid syntax 

Can it somehow be written shorter / prettier?

And why does [a.remove(item) for item in a if '8080' in item[1]] delete not all values ​​at once? That is, you need to run the expression several times to remove all matches.

And the most important question : Please tell me the most correct method of working with data in python of type key: value (as in the example above, but very much), so that you can then search by key, or by value and delete the found pair? At the moment I have a sheet of sheets with sheets (as in the example above), but I don’t like it by sight :) and I decided to translate it all into a dictionary, but as they say on the Internet, dictionaries are not intended for this.

    2 answers 2

    Using the list expression [val for val in key] implies getting the value into the list. The expression (d[key[0]] = val) returns nothing and therefore does not go to the list. Hence the error, it's like writing print (a = 1) .

    In addition, it is not clear what you want to get. After all, to get the values, it is enough to write just val , and to get the keys there is a keys() function. In any case, you should not get hung up on the fact that the code has always been shorter, this is one of the coding errors. Better to let it be clearer and faster, but not shorter.


    If you delete a value from the collection, its internal counter is rebuilt and you get the wrong value. Well, for example:

     a = ["one", "two", "three", "four"] for val in a: if val == "three": a.remove(val) print(val) 

    As soon as the cycle receives the third element, it will delete it and the fourth will replace the third one. Now there are three of them. But the cycle knows nothing about it, will not receive a new third element again, he will miss it and try to get a fourth one, which no longer exists.

    Likewise, the rebuild of the counter does not allow you to get the correct result in the cycle. Therefore, get links and then delete the items separately.


    For large amounts of key-value data, only DBs come to my mind, but I don’t know how they relate to your task. Therefore, in this matter will not help.

    • Thank you, I did not quite put it right. I do not need to store key: value for a long time, I need to keep it in memory while the script is running. That is, I need to somehow work with this: Right, convenient, fast. So I'm looking for how. And can you give an example of how to delete by reference? Well, since we are talking so heartily, maybe you can tell me why this doesn't work: pastebin.com/eDb4Afp3 :) - whoami

    Regarding the question you asked in the commentary to the answer from Alex Krass.

    If I understand correctly, you need a filter that will check that at least one port number from the template is contained in the port numbers in the elements of the main list.

    In this case, you need this:

     fl = ['8080', '4662'] a = [(['192.168.0.1'], ['8080']), (['192.168.0.2'], ['4662']), (['192.168.0.3'], ['8080', '4662']), (['192.168.0.4'], ['8080', '4662']), (['192.168.0.5'], ['8080', '4662']), (['192.168.0.6'], ['8080']), (['192.168.0.8'], ['80', '443'])] result = filter(lambda x: (any([f in x[1] for f in fl])), a) print(list(result))