Skip to content

78. Subsets #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

78. Subsets #51

wants to merge 1 commit into from

Conversation

fhiyo
Copy link
Owner

@fhiyo fhiyo commented Jul 23, 2024

```py
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
def subsets_helper(subset: list[int], index: int) -> Iterator[list[int]]:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yield や yeild from は、読んでいてやや認知負荷が高く感じられました。 List[List[int]] に一つずつ追加しているコードのほうが読みやすく感じました。

def subsets(self, nums: List[int]) -> List[List[int]]:
all_subsets = []
for i in range(len(nums) + 1):
all_subsets.extend(map(lambda t: list(t), self._my_combinations(nums, i)))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mapとlambdaを組み合わせるのは正直結構読みにくく感じました。
effective pythonにもそう書かれていた気がします(ちょうど最近読んだ項目)、とある方のメモ
https://scrapbox.io/nikkie-memos/%E9%A0%85%E7%9B%AE27_map%E3%82%84filter%E3%81%AE%E4%BB%A3%E3%82%8F%E3%82%8A%E3%81%AB%E3%83%AA%E3%82%B9%E3%83%88%E5%86%85%E5%8C%85%E8%A1%A8%E8%A8%98%E3%82%92%E4%BD%BF%E3%81%86

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほど、ありがとうございます。こんな感じですかね?

all_subsets.extend(list(t) for t in self._my_combinations(nums, i))

for i in range(2 ** len(nums)):
subset = []
for j in range(i.bit_length()):
if (i >> j) & 1:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

個人的にこれがi, jなのはやや読みにくく感じました(変数名)
jはnum_shiftとか?(iはパッと思いつかない…)

def subsets(self, nums: List[int]) -> List[List[int]]:
def generate_subsets() -> Iterator[list[int]]:
for i in range(2 ** len(nums)):
selector = map(lambda b: b == '1', reversed(f"{i:0{len(nums)}b}"))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こっちも上と同様で、さらに中にreversedとかlenがあるとかなり認知負荷がありました

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちらもこうですかね

bit_pattern = f"{i:0{len(nums)}b}"
selector = (b == '1' for b in reversed(bit_pattern))
yield compress(nums, selector)



あえて[itertools.combinations()](https://docs.python.org/3.11/library/itertools.html#itertools.combinations)を実装して解く。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_subsets.append(subset + [num])
all_subsets.extend(new_subsets)
return all_subsets
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

変な物を書いてみました。

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        result = [[]]
        for n in nums:
            x = map(tee, result)
            y = list(map(lambda a: (chain(a[0], [n]), a[1]), x))
            result = chain.from_iterable(y)
        return map(list, result)

n が評価される瞬間が遅延しているので、list がいります。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちらのほうがかわいいでしょうか。

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        def f(n, it):
            a, b = tee(it)
            return [chain(a, [n]), b]
        result = [[]]
        for n in nums:
            result = chain.from_iterable(map(partial(f, n), result))
        return result

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

後者が遅延評価されないのって、partialを使うことでpartial(f, n)の評価自体はその場で行われるようにしてるから、ってことでいいんですかね?
partial(f, n)の代わりに lf = lambda it: f(n, it) みたいなのをforループの中で定義してmapの第一引数に指定してもlfの評価は遅延されるのでnはループが終わった後のものを参照してしまう。


調べたメモ:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants