---
# System prepended metadata

title: Python Notes

---

# Python Notes
## Rules
1. Language: English (90%)
2. Notes for one person per week:
    * Arrmen >2
    * Tsr >2 
3. Add name to let us know who u r
4. Can add tags to classify
5. Welcome comments
--- 
### Arrmen / 111019 [#jupyter]()
This note will give a brief start up for .NET development on Jupyter Notenook.
#### Background
Since Nov., the extension tool Try.Net can support developer write .NET code on Jupyter Notebooks.
#### Enviroment Requirement
* Jupyter Notebooks
* [.NET Core 3.0 SDK](https://dotnet.microsoft.com/download/dotnet-core/3.0)
* [.NET Core 2.1](https://dotnet.microsoft.com/download/dotnet-core/2.1) (for Try.net)
* Try.NET Global Tool 2.1
    in .NET core cli
    ```
    dotnet tool install -g dotnet-try
    ```
* Ananconda Prompt (only for startup)
#### Startup
1. Open Ananconda Prompt to install .NET kernel
    ```
    dotnet try jupyter install
    ```
2. (Optional) Check to see if the .NET kernel is installed
    ```
    jupyter kernelspec list
    ```
3. Start a new notebook, u will see C# or F# notebook option, like image below.
![](https://i.imgur.com/pAXODLy.png)
#### Reference
* [Microsoft Announcement](https://devblogs.microsoft.com/dotnet/net-core-with-juypter-notebooks-is-here-preview-1/)
* [News from iThome](https://www.ithome.com.tw/news/134068)
### Tsr / 110919 [#python]()
**Difference between * and np.dot or np.matmul**
 '* is only for multiplacing corresponding array elements
 do not use '*' for matrix multiplcation! 
### Arrmen / 110419 [#python]() [#performance]()
This note will give a brief introduction of implementation of python.
<style>
.row-container {
    width: 100%;
    display: flex;
    justify-content: space-around;
    align-items: center;
}
.bridge {
    text-align: center
}
</style>
<div class="row-container">
    <p>code</p>
    <p class="bridge">interpreter<br>--------------></p>
    <p>byte code</p>
    <p class="bridge">complier<br>--------------></p>
    <p>machine code</p>
</div>

1. interpreter: byte code can run on different OS, common interpreters like


| Interpreter | Feature                          |
| ----------- | -------------------------------- |
| CPython     | transfer to C byte code          |
| Jython      | transfer to Java byte code       |
| PyPy        | transfer to **Python** byte code |
| PythonNet   | Mono byte code                   |
| IronPython  | .NET byte code                   |
2. complier: virtual machine, common compliers like


| Complier | Handle code      | Feature                                                     |
| -------- | ---------------- | ----------------------------------------------------------- |
| C        | C byte code      | usually small and fast                                      |
| JVM      | Java byte code   | equal to Java virtual machine                               |
| CLR      | VB, C# byte code | **only on Windows**; abbreviation of "Common Language Run-time" |
| Mono     | VB, C# byte code | **cross OS**.                                               |
* [Mono](https://en.wikipedia.org/wiki/Mono_(software)): a virtual machine based on .Net
* Tips: change interpreter in PyCharm
    * In PyCharm(v2019.1.3): `File` > `Settings...` > left navigaton `Project interpreter` > top input of right side `Project interpreter` selector 
### Arrmen / 102919 [#python]()
**Python version: ^3.6.0**
This notes will give a brief introduction of sorting function in python. 
* **Two function**
    1. `<list>.sort(<iterable object>[, key=<sort key function>, reverse=<bool>])`
    2. `sorted(<iterable object>[, key=<sort key function>, reverse=<bool>])`
* For Python ^2.2.0, sorting function is **stable** 
* Python has used [Timsort](https://en.wikipedia.org/wiki/Timsort) since v2.3.0
* Minimum sorted result has 0 as index without reverse
```python
    example_list_1 = ['Renault', 'Citroen', 'Peugeot', 'Renault']
    example_list_3 = [('Renault', 2), ('Citroen',), ('Peugeot',), ('Renault', 1)]
    example_set = {'Renault', 'Citroen', 'Peugeot'}
    example_tuple = ('Renault', 'Citroen', 'Peugeot')
    
    # sorted() return a <list> without modifiying original data
    example_list_1	         # -> ['Renault', 'Citroen', 'Peugeot', 'Renault']
    example_list_1.sort()       # -> <class 'NoneType'>
    type(example_list_1.sort()) # -> None
    example_list_1	         # -> ['Citroen', 'Peugeot', 'Renault', 'Renault']
    
    # <list>.sort() change data of list, return None
    example_list_1	          # -> ['Renault', 'Citroen', 'Peugeot', 'Renault']
    sorted(example_list_1)       # -> ['Citroen', 'Peugeot', 'Renault', 'Renault']
    type(sorted(example_list_1)) # -> <class 'list'>
    example_list_1	          # -> ['Renault', 'Citroen', 'Peugeot', 'Renault']
    
    # Reverse
    sorted(example_list_1, reverse=True) # -> ['Renault', 'Renault', 'Peugeot', 'Citroen']
    
    # Sort other type iterable object
    sorted(example_set)            # -> ['Citroen', 'Peugeot', 'Renault']
    type(sorted(example_set))      # -> <class 'list'>
    sorted(example_tuple)          # -> ['Citroen', 'Peugeot', 'Renault']
    type(sorted(example_tuple))    # -> <class 'list'>
    sorted('example string')       # -> [' ', 'a', 'e', 'e', 'g', 'i', 'l', 'm', 'n', 'p', 'r', 's', 't', 'x']
    type(sorted('example string')) # -> <clas 'list'>
    
    # Sorted by provided key
    sorted(example_list_1, key=lambda x: x[1])          # -> ['Renault', 'Peugeot', 'Renault', 'Citroen'] -> only sorted by second character
    sorted(example_list_1, key=lambda x: x[1:len(x)-1]) # -> sorted by [1:string end]
    
    # Stable sort probement
    sorted(example_list_3, key=lambda example: example[0]) # -> [('Citroen',), ('Peugeot',), ('Renault', 2), ('Renault', 1)] -> need to limit sorting reference
    
    example_list_3.sort(key=lambda example: example[0])
    example_list_3 # -> [('Citroen',), ('Peugeot',), ('Renault', 2), ('Renault', 1)] -> need to limit sorting reference too
```
#### Reference
* [3.6.9 Official Document](https://docs.python.org/3.6/howto/sorting.html#sort-stability-and-complex-sorts)
### Tsr / 102519 [#python]()
**(Difference between \*args and \*\*kwargs)**
> def myFun(arg1, *argv): 
    print ("First argument :", arg1) 
    for arg in argv: 
        print("Next argument through *argv :", arg) 
        myFun(**<u>'Hello'</u>**, 'Welcome', 'to', 'GeeksforGeeks')
vs 
def myFun(\*\*kwargs):
    for key, value in kwargs.items(): 
        print ("%s == %s" %(key, value)) 
myFun(**<u>first=</u>**'Geeks', mid ='for', last='Geeks')

**lambda example when used in indexing**
> X.loc[lambda f: f.category_name =='comp.graphics'].iloc[::10][:5]

from lambda f, all rows in X with category name, comp.graphics is fetched
from X.loc[], the resulting rows from previous query is queried and forms a dataframe
this resulting dataframe is iloc using index, a vector of [start: end:interval](parameters of iloc)[start:end](slicing the results)

### Tsr / 102119 [#python]()
**Typical visualisation using matplotlib.pyplot**
- plt.subplots(figsize=(9, 7)) # subplots. can explore other parameters. Figsize is especially useful in **jupyter notebook** so that the diagram fits in the browser 
- x = sent_tag_dic.keys() # x values
- y = [len(sent_tag_dic[k]) for k in sent_tag_dic.keys()] # y values
- plt.bar(x, y) # visualisation model
- plt.show() # to show the graphs, can be executed after running a few blocks of (subplot, bar)

**Comments on zip()**
Definition: The zip() function returns an iterator of tuples based on the iterable object.
- If no parameters are passed, zip() returns an empty iterator
- If a single iterable is passed, zip() returns an iterator of 1-tuples. Meaning, the number of elements in each tuple is 1.
- If multiple iterables are passed, ith tuple contains ith Suppose, two iterables are passed; one iterable containing 3 and other containing **5** elements. Then, the returned iterator has **3** tuples. It's because iterator stops when **<u>*shortest*</u>** iterable is exhaused.
### Arrmen / 102019 [#python]()
This note will give some funny ways of quickly initializing an iterable object with default value.
-> iterable object: includes `list`, `tuple`, `set`...
```python=
    # 1. Use for-loop
    [i*i for i in range(5)] # -> [0, 1, 4, 9, 16]
    {'Hi' for i in range(5)} # -> {'Hi'} -> because it's a set
    (i*i for i in range(5)) # -> <generator object <genexpr> at 0x...>
    type(i*i for i in range(5)) # -> <class 'generator'>
    tupe(i*i for i in range(5)) # -> (0, 1, 4, 9, 16)
    i*i for i in range(5) # -> SyntaxError: invalid syntax
    
    # 1.5 Complex case: combine with zip(), map(), enumerate()...
    example_list_1 = ['Mazda', 'ISUZU', 'MINI'];
    ['index of {} is {}'.format(car, index) for index, car in enumerate(example_list_1)]
    # -> ['index of Mazda is 0', 'index of ISUZU is 1', 'index of MINI is 2']
    
    # 2. With operator; only for times operator
    # ! This method doesn't support <set> object
    ['Hi'] * 5 # -> ['Hi', 'Hi', 'Hi', 'Hi', 'Hi']
    list('Hi') * 5 # -> ['H', 'i', 'H', 'i', 'H', 'i', 'H', 'i', 'H', 'i']
    [2] * 5 # -> [2, 2, 2, 2, 2]
    list(2) * 5 # -> TypeError: 'int' object is not iterable
    ('Hi',) * 5 # -> ('Hi', 'Hi', 'Hi', 'Hi', 'Hi')
    tuple('Hi') # -> ('H', 'i', 'H', 'i', 'H', 'i', 'H', 'i', 'H', 'i')
```
#### Reference
* [Thispointer.com](https://thispointer.com/python-how-to-create-a-list-and-initialize-with-same-values/), 03/04/18
### Arrmen / 101519 [#python]() [#file]()
This note will give an introduction of handling **.txt file**
Content in _example.txt_
```
Bently
Volkswagen
```
0. Open file `open(<path with file name> [, <mode>])`: 'mode' can be refered from [W3School](https://www.w3schools.com/python/python_file_handling.asp), example
``` python=
file = open('example.txt', 'a+')
print(type(file)) # -> <class '_io.TextIOWrapper'>`
```
2. Close file `close()`: example `file.close()`
3. Read: **can't read file multiple times(see below examples), so use a variable to store contents at first**
``` python=
    file = open('example.txt', 'r')
    # read()
    print(file.read()) # -> Bently /n Vlokswagen
    print(file.read()) # -> if u call this function many times,
                       # it will return nothing after first call,
                       # because file has been read end

    # read a single line: readline()
    print(file.readline(), file.readline()) # -> Bently /n Vlokswagen

    # divide contents by line: readlines() -> <class list>
    # improper solution
    for line in file.readlines():
        print(line) # -> [] -> because file has been read completely at first call 'readlines()'
    # better solution
    line_list = file.readlines()
    for line in line_list:
        print(line) # -> Bently /n Vlokswagen
```
3. Write
``` python=
    file = open('example.txt', 'a+')
    # write single value: write(<string>>), return int(length of <string>)
    file.write('\nBugatti') # -> Bently \n Volkswagen \n Bugatti

    # write multiple values at once: writeines(<string list>), return <None>
    file.writelines(['\nSaab', '\nScania']) # -> Bently \n Volkswagen \n Saab \n Scania
```
4. Delete: needs to import package `os`
``` python
    import os
    # remove single file: remove(<path with file name)
    os.remove('example.txt')    
```
5. Create: can automatically be done when mode is 'a' or 'w', but also can use mode 'x'. Remember add **file extension**
``` python=
    # Create example.txt if it doesn't exist
    open('example.txt', 'x')
    
    # Create multiple type of file with file extension if it doesn't exist
    open('example.png', 'x') # -> create a .png
```
* Tips: use `close()` to update file's state 
``` python=
    file_write = open('example.txt', 'a+')
    file_read = open('example.txt', 'r')
    file_write.write('\nSuzuki')
    file_write.close()
    print(file_read.read()) # print Bently \n Volkswagen \n Suzuki
                            # same as content in example.txt
    file_write = open('example.txt', 'a+')
    file_read = open('example.txt', 'r') # open and write
    file_write.write('\nSuzuki')
    print(file_read.read()) # print Bently \n Volkswagen
                            # but content in example.txt is Bently \n Volkswagen \n Suzuki
    file_write = open('example.txt', 'a+')
    file_write.write('\nSuzuki') # write and open
    file_read = open('example.txt', 'r')
    print(file_read.read()) # print Bently \n Volkswagen
                            # but content in example.txt is Bently \n Volkswagen \n Suzuki
```
#### Reference
* [Python file handling](https://www.guru99.com/reading-and-writing-files-in-python.html)
* [W3School](https://www.w3schools.com/python/python_file_handling.asp)
### Arrmen / 101319 [#python]() [#application]()
This note will give 2 funny functions related to 'list'.
1. Filter `filter(<function>, <iterable object>)`, return a `<class 'filter'>` instead of a `<iterable object>` 
    * **Usage:** check whether every element satisfies the conditional function. If passed, put it into a 'filter' object
    * same as [`map()`](https://hackmd.io/vG-86mkjQrWnsRn3qB1aVA?both#Arrmen--101319-python-application1)
``` python=
    def example_func(x):
        return x > 3
    
    list_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    set_1 = {2, 5, 6, 8, 9}
    tuple_1 = (2, 5, 6, 8, 9)

    filter(example_func, list_1) # -> <filter object at 0x...>
    list(filter(example_func, list_1)) # -> [4, 5, 6, 7, 8, 9, 10]
    
    # Use lambda instead of function
    list(filter(lambda x: x > 5, list_1)) # -> [6, 7, 8, 9, 10]
    
    # Support many iterable objects
    list(filter(lambda x: x > 5, set_1) # -> [6, 8, 9]
    list(filter(lambda x: x > 5, tuple_1) # -> [6, 8, 9]
    list(filter(lambda x:x > 'g', 'example string')) # -> ['x', 'm', 'p', 'l', 's', 't', 'r', 'i', 'n']
    # -> character can compare directly with ascii code

    # Support many output type
    set(filter(lambda x: x > 5, list_1)) # -> {6, 7, 8, 9, 10}
    tuple(filter(lambda x: x > 5, list_1)) # -> (6, 7, 8, 9, 10)
```
2. Zip `zip(<iterable object>[, <iterable object>, ...])`, return a `<class 'zip'>` instead of a `<iterable object>` 
    * **Usage:** combine multiple iterable object element with **same index** into **tuple**, and put tuple into 'zip' class
``` python=
    list_1 = [1, 2, 3, 4, 5]
    list_2 = [6, 7, 8, 9, 10]
    set_1 = {1, 2, 3 ,4, 5}
    tuple_1 = (6, 7, 8, 9, 10)

    zip(list_1, list_2) # -> <zip object at 0x...>
    list(zip(list_1, list_2)) # -> [(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]
    
    # Support many/multiple iterable objects
    list(zip(set_1, tuple_1)) # -> [(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]
    list(zip('Luxgen', 'Lamborgnini')) # -> [('L', 'L'), ('u', 'a'), ('x', 'm'), ('g', 'b'), ('e', 'o'), ('n', 'r')]
    list(zip(set_1, tuple_1, 'Lexus')) # -> [(1, 6, 'L'), (2, 7, 'e'), (3, 8, 'x'), (4, 9, 'u'), (5, 10, 's')]

    # Support many output type
    set(zip(list_1, list_2)) # -> {(2, 7), (5, 10), (4, 9), (3, 8), (1, 6)} -> unindex is correct
    tuple(zip(list_1, list_2)) # -> ((1, 6), (2, 7), (3, 8), (4, 9), (5, 10))
    
    # Combine with filter/map
    def compare_function(tuple_param):
        element_from_list_1 = tuple_param[0]
        element_from_list_2 = tuple_param[1]
        return element_from_list_2 > element_from_list_1*2 + 2

    list(filter(compare_function, zip(list_1, list_2))) # -> [(1, 6), (2, 7)]

    # Loop with zip
    for list_1_element, list_2_element in zip(list_1, list_2):
        print(list_1_element, list_2_element) # -> 1 6/2 7/3 8/4 9/5 10
```
#### Reference
* [zip & filter introduction](https://yangfangs.github.io/2017/08/23/python-map-zip-filter-reduce/)
* [document for zip](https://docs.python.org/3/library/functions.html#zip)
* [document for filter](https://docs.python.org/3/library/functions.html#filter)
### Arrmen / 101319 [#python]() [#application]()
This note will give 2 funny tips related to 'list'.
1. String to list. Use `split(<string>|<None>, <int>)`
``` python=
    str = 'Nissan Mitsubishi Hyundai'
    str.split() # -> ['Nissan', 'Mitsubishi', 'Hyundai']
    str.split(None) # -> ['Nissan', 'Mitsubishi', 'Hyundai']
    str.split('s') # -> ['Ni', '', 'an Mit', 'ubi', 'hi Hyundai']
    str.split('ss') # -> ['Ni', 'an Mitsubishi Hyundai']
    str.split('5') # -> ['Nissan Mitsubishi Hyundai']

    # second parameter means (the max split - 1)
    str.split(None,1) # -> ['Nissan', 'Mitsubishi Hyundai']
    str.split(None,10000) # -> ['Nissan', 'Mitsubishi', 'Hyundai']
```
2. Map `map(<function>, <iterable object> [, <iterable object>, ...])`return a `<class 'map'>` instead of a `<iterable object>`
    * **Usage:** map every element and put element into a 'map'
    * Same as [filter and reduce](https://hackmd.io/vG-86mkjQrWnsRn3qB1aVA?both#Arrmen--101319-python-application)
``` python=
    def example_func(x):
        return x ** 2

    list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    map(example_func, list1) # -> <map object at 0x...>
    list(map(example_func, list1)) # -> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

    # Use lambda instead of function
    list(map(lambda x: x **2, list1)) # -> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    
    # > 1 list parameters
    list2 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
    list(map(lambda x, y: x + y, list1, list2)) # -> [11, 22, 33, 44, 55, 66, 77, 88, 99, 110]
    list(map(example_func, list1, list2)) # -> TypeError: <lambda>() takes 1 positional argument but 2 were given
    
    # Use map to create <set> and <tuple>
    set(map(example_func, list1)) # -> {1, 4, 9, 16, 25, 36, 49, 64, 81, 100}
    tuple(map(example_func, list1)) # -> (1, 4, 9, 16, 25, 36, 49, 64, 81, 100)
    
    # Use multiple types as parameters
    tuple1 = {20, 40, 60}
    list(lambda x, y: x + y, tuple1, list1) # -> [21, 42, 63]
    list(lambda x, y: x + str(y), 'example string', list1) # -> ['e1', 'x2', 'a3', 'm4', 'p5', 'l6', 'e7', ' 8', 's9', 't10']
    tuple(map(lambda x: x+1, tuple1)) # -> (21, 41, 61)
    # -> type transformation is <tuple> -> <map> -> <tuple>)
```
#### Reference
* [string split]('https://www.mkyong.com/python/python-how-to-split-a-string/')
* [map]('https://yangfangs.github.io/2017/08/23/python-map-zip-filter-reduce/')
### Arrmen / 100619 [#python]() [#data-type]()
This notes will give a basic introduction of 'tuple'
1. **Unchangeable**: not like python 'list', value in tuple can't be modified
    -> **can't** remove, append, replace, split, slice ...
    -> **can** search, count, get length
2. **allows duplicate members**, not like python 'set', python 'dict'
3. type of element in tuple doesn't need to be same; allows tuple in tuple
4. basic method or usage
``` python=
    # use below as example tuple
    exampleTuple = ("apple", "banana", "cherry", "orange", "kiwi")
    
    # get length: same as 'list'
    len(exampleTuple) # -> '5'
    
    # join tuple: same as 'list'
    tmpTuple1 = ("toyota", "ford")
    tmpTuple2 = ("volvo", "hammer")
    exampleTuple = tmpTuple1 + tmpTuple
    print(exampleTuple) # -> ("toyota", "ford", "volvo", "hammer")
    
    # access by index: same as 'list', but type of return is element itself
    exampleTuple[1] # -> "banana"
    
    # access by range: same as 'list', but type of return is tuple
    exampleTuple[0:2] # -> ("apple", "banana")
    
    # loop: same as 'list'
    for item in exampleTuple:
        print(item) # -> "apple", "banana" ...
    
    # check element is in tuple
    # also can use .count(), .index() to check
    if "apple" in exampleTuple:
        print("true") # -> "true"
        
    # create tuple
    # multiple element case -> declare directly
    exampleTuple = ("bmw", "ferrari")
    # single element case -> add comma
    exampleTuple = ("chrysler")
    type(exampleTuple) # -> "string"
    exampleTuple = ("chrysler",)
    type(exampleTuple) # -> tuple
    
    # count(value): get how many times a element duplicates
    exampleTuple.count("apple") # -> 1
    
    # index(value): get index of first matching element, throw exception as no result
    exampleTuple("banana") # -> 1
    exampleTuple("bananas") # -> error exception

```
* Tips: use `type()` to check data's type
* Tips: like python 'list', tuple support negative index, but [0] is same as [-0]
* Tips: use `exampleTuple[n:n]` will get `()`
* Tips: use `exampleTuple[n:n+1` will get `(exampleTuple[n],)` -> a tuple
* Tips: change value: can't directly change, but can transform to 'list' and transform the list again to 'tuple''
    ``` python=
    print(exampleTuple) # -> ("apple", "banana", "cherry", "orange", "kiwi")
    tmpList = list(exampleTuple)
    list[1] = "porsche"
    exampleTuple = tuple(list)
    print(exampleTuple) # -> ("apple", "porsche", "cherry", "orange", "kiwi")
    ```
* Tips: to access double tuple, use the same way as double 'list
#### Reference
* [W3School](https://www.w3schools.com/python/python_tuples.asp)
### Tsr / 100419 
- multiple assignment of string chars. e.g. t1,t2,t3='hii' t1='h'
- backslash to escape quotation e.g. circus = 'Monty Python\'s Flying Circus'
- backslash to separate codes onto multi lines (not needed if inside brackets)
- indexes: -1 is the index of the last character
- regex: re.finall(r.......) e.g. re.findall(r'^.*(ing|ly|ed|ious|ies|ive|es|s|ment)$', 'processing') *Remember to prefix regular expressions with the letter r (meaning "raw"), which instructs the Python interpreter to treat the string literally, rather than processing any backslashed characters it contains.*
- string formatting: e.g. '{}->{};'.format ('cat', 3) 'cat->3;'
    - aligning: 
    >>> '{:6}'.format(41) [1]
    '    41'        
    >>> '{:<6}' .format(41) [2]
    '41
    - sf:
    >>> '{:.4f}'.format(math.pi) '3.1416'

### Arrmen / 100219 [#python]() [#windows]() [#install]()
This notes will share how i install python at Windows 10.
[Download here](https://www.python.org/downloads/windows/), according your computer architecture (bits 64 or 32)
* Follow GUI set-up instruction, **choose folder carefully**
* How to use python in terminal?
    1. go to **'System'**(`Win` + `PAUSE`)
    2. find **'Environment variables setting'**(`Advanced system setting`)
    3. click **'Path'** option, click edit
    4. add the path to **'python.exe'**(I don't use default path, so i forget it; possibly in ../ProgramFile x86/...)
    5. apply, and test on ur terminal
* Tips: GUI = Graphic Unit Interface, CLI = Command Line Interface ~= terminal
* Tips: After initializing get-pip.py (at same folder as python.exe, usually), u can add its path (../Script) into Path too.
#### Reference
* [Set-up tutorial](https://realpython.com/installing-python/)
* [CLI setting](https://superuser.com/questions/143119/how-do-i-add-python-to-the-windows-path)

### Tsr / 100119
- install python using *homebrew* to prevent issues
- [] is a list, index starts from 0 
- trimming by indexing, e.g. [1:3] gets index 1&2 
- lambda to apply functions to each row, e.g. X['category_name'] = X.category.apply(lambda t: dmh.format_labels(t, twenty_train)) 
