|
685 | 685 | "text/markdown": [
|
686 | 686 | "---\n",
|
687 | 687 | "\n",
|
688 |
| - "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L113){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 688 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L114){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
689 | 689 | "\n",
|
690 | 690 | "### get_class\n",
|
691 | 691 | "\n",
|
|
697 | 697 | "text/plain": [
|
698 | 698 | "---\n",
|
699 | 699 | "\n",
|
700 |
| - "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L113){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 700 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L114){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
701 | 701 | "\n",
|
702 | 702 | "### get_class\n",
|
703 | 703 | "\n",
|
|
875 | 875 | "text/markdown": [
|
876 | 876 | "---\n",
|
877 | 877 | "\n",
|
878 |
| - "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L157){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 878 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L158){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
879 | 879 | "\n",
|
880 | 880 | "#### ignore_exceptions\n",
|
881 | 881 | "\n",
|
|
886 | 886 | "text/plain": [
|
887 | 887 | "---\n",
|
888 | 888 | "\n",
|
889 |
| - "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L157){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 889 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L158){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
890 | 890 | "\n",
|
891 | 891 | "#### ignore_exceptions\n",
|
892 | 892 | "\n",
|
|
2910 | 2910 | "text/markdown": [
|
2911 | 2911 | "---\n",
|
2912 | 2912 | "\n",
|
2913 |
| - "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L524){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 2913 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L525){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
2914 | 2914 | "\n",
|
2915 | 2915 | "#### GetAttr\n",
|
2916 | 2916 | "\n",
|
|
2921 | 2921 | "text/plain": [
|
2922 | 2922 | "---\n",
|
2923 | 2923 | "\n",
|
2924 |
| - "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L524){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
| 2924 | + "[source](https://github.com/AnswerDotAI/fastcore/blob/master/fastcore/basics.py#L525){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", |
2925 | 2925 | "\n",
|
2926 | 2926 | "#### GetAttr\n",
|
2927 | 2927 | "\n",
|
|
3601 | 3601 | "outputs": [],
|
3602 | 3602 | "source": [
|
3603 | 3603 | "#|export\n",
|
| 3604 | + "def _conv_key(k):\n", |
| 3605 | + " if isinstance(k,int): return itemgetter(k)\n", |
| 3606 | + " elif isinstance(k,str): return attrgetter(k)\n", |
| 3607 | + " elif isinstance(k,tuple): return lambda x: tuple(_conv_key(o)(x) for o in k)\n", |
| 3608 | + " return k\n", |
| 3609 | + "\n", |
3604 | 3610 | "def groupby(x, key, val=noop):\n",
|
3605 | 3611 | " \"Like `itertools.groupby` but doesn't need to be sorted, and isn't lazy, plus some extensions\"\n",
|
3606 |
| - " if isinstance(key,int): key = itemgetter(key)\n", |
3607 |
| - " elif isinstance(key,str): key = attrgetter(key)\n", |
3608 |
| - " if isinstance(val,int): val = itemgetter(val)\n", |
3609 |
| - " elif isinstance(val,str): val = attrgetter(val)\n", |
| 3612 | + " key = _conv_key(key)\n", |
| 3613 | + " val = _conv_key(val)\n", |
3610 | 3614 | " res = {}\n",
|
3611 | 3615 | " for o in x: res.setdefault(key(o), []).append(val(o))\n",
|
3612 | 3616 | " return res"
|
|
3625 | 3629 | "cell_type": "markdown",
|
3626 | 3630 | "metadata": {},
|
3627 | 3631 | "source": [
|
3628 |
| - "Here's an example of how to *invert* a grouping, using an `int` as `key` (which uses `itemgetter`; passing a `str` will use `attrgetter`), and using a `val` function:" |
| 3632 | + "You can use an `int` as `key` or `val` (which uses `itemgetter`; passing a `str` will use `attrgetter`), eg:" |
| 3633 | + ] |
| 3634 | + }, |
| 3635 | + { |
| 3636 | + "cell_type": "code", |
| 3637 | + "execution_count": null, |
| 3638 | + "metadata": {}, |
| 3639 | + "outputs": [], |
| 3640 | + "source": [ |
| 3641 | + "test_eq(groupby('aa ab bb'.split(), 0), {'a':['aa','ab'], 'b':['bb']})" |
| 3642 | + ] |
| 3643 | + }, |
| 3644 | + { |
| 3645 | + "cell_type": "markdown", |
| 3646 | + "metadata": {}, |
| 3647 | + "source": [ |
| 3648 | + "...and you can use a tuple as `key` or `val` (which creates a tuple from the provided keys or vals), eg:" |
| 3649 | + ] |
| 3650 | + }, |
| 3651 | + { |
| 3652 | + "cell_type": "code", |
| 3653 | + "execution_count": null, |
| 3654 | + "metadata": {}, |
| 3655 | + "outputs": [], |
| 3656 | + "source": [ |
| 3657 | + "test_eq(groupby('aaa abc bba'.split(), 0, (1,2)), {'a':[('a','a'),('b','c')], 'b':[('b','a')]})" |
| 3658 | + ] |
| 3659 | + }, |
| 3660 | + { |
| 3661 | + "cell_type": "markdown", |
| 3662 | + "metadata": {}, |
| 3663 | + "source": [ |
| 3664 | + "Here's an example of how to *invert* a grouping, and using a `val` function:" |
3629 | 3665 | ]
|
3630 | 3666 | },
|
3631 | 3667 | {
|
|
0 commit comments