groupby.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. # Purpose: Grouping entities by DXF attributes or a key function.
  2. # Created: 03.02.2017
  3. # Copyright (C) 2017, Manfred Moitzi
  4. # License: MIT License
  5. from typing import Callable, Iterable, Hashable, Dict, List, TYPE_CHECKING
  6. from ezdxf.lldxf.const import DXFValueError, DXFAttributeError
  7. if TYPE_CHECKING:
  8. from ezdxf.eztypes import DXFEntity, KeyFunc
  9. def groupby(entities: Iterable['DXFEntity'], dxfattrib: str = '', key: 'KeyFunc' = None) \
  10. -> Dict[Hashable, List['DXFEntity']]:
  11. """
  12. Groups a sequence of DXF entities by an DXF attribute like 'layer', returns the result as dict. Just specify
  13. argument `dxfattrib` OR a `key` function.
  14. Args:
  15. entities: sequence of DXF entities to group by a key
  16. dxfattrib: grouping DXF attribute like 'layer'
  17. key: key function, which accepts a DXFEntity as argument, returns grouping key of this entity or None for ignore
  18. this object. Reason for ignoring: a queried DXF attribute is not supported by this entity
  19. Returns: dict
  20. """
  21. if all((dxfattrib, key)):
  22. raise DXFValueError('Specify a dxfattrib or a key function, but not both.')
  23. if dxfattrib != '':
  24. key = lambda entity: entity.get_dxf_attrib(dxfattrib, None)
  25. if key is None:
  26. raise DXFValueError('no valid argument found, specify a dxfattrib or a key function, but not both.')
  27. result = dict()
  28. for dxf_entity in entities:
  29. try:
  30. group_key = key(dxf_entity)
  31. except DXFAttributeError: # ignore DXF entities, which do not support all query attributes
  32. continue
  33. if group_key is not None:
  34. group = result.setdefault(group_key, [])
  35. group.append(dxf_entity)
  36. return result