处理列表和使用 mypy 时如何减少冗长?
How to reduce verobsity when dealing with lists and using mypy?
我只是在工作中写这类东西,想知道是否有任何 pythonic 方法来减少与列表、迭代器和集合处理相关的无关内容 Item.display()。
在 Item.display() 中是否有更多 pythonic 方式来处理过滤和转换?
有什么方法可以让我使用不同的字体来简化打字吗?
import unittest
from dataclasses import dataclass, field
from typing import Union, Tuple, List, Iterator
@dataclass
class Category:
id: str
name: str = field(compare=False)
canonical: Union['Category', None] = field(compare=False)
def __hash__(self)->int:
return self.id.__hash__()
def unalias(self)->'Category':
#There could be more tests here
if self.canonical:
return self.canonical
else:
return self
def display_str(self)->str:
if self.id and self.name:
return f'{self.id} [{self.name}]'
else:
return self.id
@dataclass
class Item:
id: str
categories: List[Category]
def display(self,primary:Category)-> List[str]:
"""Unalias, dedup and sort for display."""
if not self.categories:
return []
def unalias(secs:Iterator[Category])->Iterator[Category]:
return map(lambda c: c.unalias(), secs)
def de_prim(secs:Iterator[Category])->Iterator[Category]:
return filter(lambda c: c.id != primary.id, secs)
def to_display(secs:List[Category])->List[str] :
return list(map(lambda c: c.display_str(), secs) )
de_primaried = set(de_prim(unalias(iter(self.categories))))
if not de_primaried:
return []
return sorted(to_display(de_primaried))
class DoiTest(unittest.TestCase):
def test(self):
primary = Category('shirt', 'Shirts', None)
cats = [Category('snow','Snowflakes',
Category('frozen_water','Frozen Water',None) ),
Category('t-shirt','Tee Shirts', primary),
Category('cheese','Yummy Cheese',None)]
item = Item( 'ItemX', cats)
self.assertEqual( item.display(primary) , ['cheese [Yummy Cheese]', 'frozen_water [Frozen Water]'])
去掉 mypy 位,看起来这就是您正在做的事情?
def display(self, primary):
return sorted(
map(
lambda c: c.display_str(),
set(
filter(
lambda c: c.id != primary.id,
map(
lambda c: c.unalias(),
self.categories
)
)
)
)
)
除非您希望 categories
具有值 None
,否则我会将其初始化为一个空列表。由于 de_primaried
将始终是 map 的有效参数,即使它是空的,也无需检查它并手动 return 一个空列表。
您可能需要考虑在几个嵌套循环中构建您的 return 值以提高可读性(在我看来,其中的一次性函数绝对不是可行的方法,特别是考虑到额外的类型混乱)。另外,我完全有可能遗漏了一些东西,但那里似乎有一些不必要的 list()
和 iter()
调用。
我只是在工作中写这类东西,想知道是否有任何 pythonic 方法来减少与列表、迭代器和集合处理相关的无关内容 Item.display()。
在 Item.display() 中是否有更多 pythonic 方式来处理过滤和转换?
有什么方法可以让我使用不同的字体来简化打字吗?
import unittest
from dataclasses import dataclass, field
from typing import Union, Tuple, List, Iterator
@dataclass
class Category:
id: str
name: str = field(compare=False)
canonical: Union['Category', None] = field(compare=False)
def __hash__(self)->int:
return self.id.__hash__()
def unalias(self)->'Category':
#There could be more tests here
if self.canonical:
return self.canonical
else:
return self
def display_str(self)->str:
if self.id and self.name:
return f'{self.id} [{self.name}]'
else:
return self.id
@dataclass
class Item:
id: str
categories: List[Category]
def display(self,primary:Category)-> List[str]:
"""Unalias, dedup and sort for display."""
if not self.categories:
return []
def unalias(secs:Iterator[Category])->Iterator[Category]:
return map(lambda c: c.unalias(), secs)
def de_prim(secs:Iterator[Category])->Iterator[Category]:
return filter(lambda c: c.id != primary.id, secs)
def to_display(secs:List[Category])->List[str] :
return list(map(lambda c: c.display_str(), secs) )
de_primaried = set(de_prim(unalias(iter(self.categories))))
if not de_primaried:
return []
return sorted(to_display(de_primaried))
class DoiTest(unittest.TestCase):
def test(self):
primary = Category('shirt', 'Shirts', None)
cats = [Category('snow','Snowflakes',
Category('frozen_water','Frozen Water',None) ),
Category('t-shirt','Tee Shirts', primary),
Category('cheese','Yummy Cheese',None)]
item = Item( 'ItemX', cats)
self.assertEqual( item.display(primary) , ['cheese [Yummy Cheese]', 'frozen_water [Frozen Water]'])
去掉 mypy 位,看起来这就是您正在做的事情?
def display(self, primary):
return sorted(
map(
lambda c: c.display_str(),
set(
filter(
lambda c: c.id != primary.id,
map(
lambda c: c.unalias(),
self.categories
)
)
)
)
)
除非您希望 categories
具有值 None
,否则我会将其初始化为一个空列表。由于 de_primaried
将始终是 map 的有效参数,即使它是空的,也无需检查它并手动 return 一个空列表。
您可能需要考虑在几个嵌套循环中构建您的 return 值以提高可读性(在我看来,其中的一次性函数绝对不是可行的方法,特别是考虑到额外的类型混乱)。另外,我完全有可能遗漏了一些东西,但那里似乎有一些不必要的 list()
和 iter()
调用。