Join the components from each DataFlow. See below for its behavior. Note that you can't join a DataFlow that produces lists with one that produces dicts. Example: .. code-block:: none df1 produces: [c1, c2] df2 produces: [c3, c4] joined: [c1, c2, c3, c4]
| 520 | |
| 521 | |
| 522 | class JoinData(DataFlow): |
| 523 | """ |
| 524 | Join the components from each DataFlow. See below for its behavior. |
| 525 | |
| 526 | Note that you can't join a DataFlow that produces lists with one that produces dicts. |
| 527 | |
| 528 | Example: |
| 529 | |
| 530 | .. code-block:: none |
| 531 | |
| 532 | df1 produces: [c1, c2] |
| 533 | df2 produces: [c3, c4] |
| 534 | joined: [c1, c2, c3, c4] |
| 535 | |
| 536 | df1 produces: {"a":c1, "b":c2} |
| 537 | df2 produces: {"c":c3} |
| 538 | joined: {"a":c1, "b":c2, "c":c3} |
| 539 | """ |
| 540 | |
| 541 | def __init__(self, df_lists): |
| 542 | """ |
| 543 | Args: |
| 544 | df_lists (list): a list of DataFlow. |
| 545 | When these dataflows have different sizes, JoinData will stop when any |
| 546 | of them is exhausted. |
| 547 | The list could contain the same DataFlow instance more than once, |
| 548 | but note that in that case `__iter__` will then also be called many times. |
| 549 | """ |
| 550 | self.df_lists = df_lists |
| 551 | |
| 552 | try: |
| 553 | self._size = len(self.df_lists[0]) |
| 554 | for d in self.df_lists: |
| 555 | assert len(d) == self._size, \ |
| 556 | "All DataFlow must have the same size! {} != {}".format(len(d), self._size) |
| 557 | except Exception: |
| 558 | logger.info("[JoinData] Size check failed for the list of dataflow to be joined!") |
| 559 | |
| 560 | def reset_state(self): |
| 561 | for d in set(self.df_lists): |
| 562 | d.reset_state() |
| 563 | |
| 564 | def __len__(self): |
| 565 | """ |
| 566 | Return the minimum size among all. |
| 567 | """ |
| 568 | return min(len(k) for k in self.df_lists) |
| 569 | |
| 570 | def __iter__(self): |
| 571 | itrs = [k.__iter__() for k in self.df_lists] |
| 572 | try: |
| 573 | while True: |
| 574 | all_dps = [next(itr) for itr in itrs] |
| 575 | if isinstance(all_dps[0], (list, tuple)): |
| 576 | dp = list(itertools.chain(*all_dps)) |
| 577 | else: |
| 578 | dp = {} |
| 579 | for x in all_dps: |
no outgoing calls
no test coverage detected
searching dependent graphs…