Почему методы set, такие как .intersection (), не поддерживаются в объектах, похожих на set? - PullRequest
0 голосов
/ 01 ноября 2018

В Python 3.7 я хотел бы рассчитать пересечение ключей двух словарей. Для этого я бы хотел вызвать метод .intersection() на их keys(), однако он не работает.

.keys () создает объект, подобный множеству, однако большинство методов множества не работают с ним. Однако работают крайне неизвестные побитовые операторные перегрузки для объектов, подобных множеству, например &.

m = {'a':1, 'b':2}
n = {'b':3, 'c':4}

m.keys().intersection(n.keys())  # Pythonic, but doesn't work

m.keys() & n.keys()  # works but not readable

set(m.keys()).intersection(set(n.keys()))  # works, readable, but too verbose

Я считаю, что перегрузка & для подобного множеству объекта используется крайне редко и не известна большинству программистов. Имена методов, такие как .intersection() или .union(), являются самодокументируемыми и определенно более Pythonic по этому определению.

Почему тогда не поддерживается? Даже в документации перечислены методы & и .intersection(), такие как псевдонимы, не говоря уже о том, что для объектов, подобных множеству, поддерживается только &.

примечание: По какой-то причине в IPython автозаполнение перечисляет .isdisjoin() в качестве метода, доступного для dict.keys(). Из 17 заданных методов 1 присутствует.

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

dict представления гарантируют только API collections.abc.Set, не эквивалентный set самому:

Для множественных представлений доступны все операции, определенные для абстрактного базового класса collections.abc.Set (например, ==, < или ^).

То есть они не претендуют на совпадение с set или даже frozenset, просто collections.abc.Set collections.abc.Set не требует ни одного из названных методов, кроме isdisjoint (который не имеет операторного эквивалента).

Что касается , почему collections.abc.Set не требует именованных методов, это может быть потому, что они несколько более сложны (большинство принимают varargs, а varargs могут быть любыми итеративными, а не просто другими наборами). как вещи, так что вы можете, например, intersection со многими итерациями одновременно), и они, возможно, хотели ограничить сложность, необходимую для реализации новых подклассов (особенно виртуальных подклассов, которые не наследовали бы ни один из методов collections.abc.Set может предоставить).

Все, что сказано, я в целом согласен с вашей точкой зрения, что кажется ненужным непоследовательным опускать формы методов. Я бы порекомендовал вам открыть ошибку на трекере ошибок Python с запросом на изменение; только то, что он гарантирует только Set совместимость, не означает, что он не может сделать больше.

0 голосов
/ 01 ноября 2018

Формат должен быть

set.intersection(*others)

, где другие - любые итерируемые. m.keys () - это dict_keys, а не набор, поэтому он не будет работать.

set(m.keys()).intersection(n.keys())

будет работать :) 1007 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...