Python(Head First)学习笔记:五

5 推导数据:处理数据、格式、编码、解码、排序

  处理数据:从Head First Python 上下载资源文件,即:james.txt,julie.txt,mikey.txt,sarah.txt。

  实例一:打开以上文件,将数据提取到列表中

>>> with open('james.txt') as jaf:
    data = jaf.readline()
    james = data.strip().split(',')
    with open('julie.txt')as juf:
        data = juf.readline()
        julie = data.strip().split(',')

        
>>> print(james)
['2-34', '3:21', '2.34', '2.45', '3.01', '2:01', '2:01', '3:10', '2-22']
>>> print(julie)
['2.59', '2.11', '2:11', '2:23', '3-10', '2-23', '3:10', '3.21', '3-21']
>>> with open('mikey.txt')as mif:
    data = mif.readline()
    mikey = data.strip().split(',')
    with open('sarah.txt')as saf:
        data = saf.readline()
        sarah = data.strip().split(',')

        
>>> print(mikey)
['2:22', '3.01', '3:01', '3.02', '3:02', '3.02', '3:22', '2.49', '2:38']
>>> print(sarah)
['2:58', '2.58', '2:39', '2-25', '2-55', '2:54', '2.18', '2:55', '2:55']
View Code

  data.strip().split(','),这种形式的代码段叫方法串链(method chaining)。

  第一个方法strip()应用到data中的数据行,这个方法会去除字符串中不想要的空白符;

  第二个方法split(',')会创建一个列表;

  采用这种方法可以把多个方法串链接在一起,生成所需要的结果。从左到右读。

  排序:有两种方式

    一、原地排序(In-plice sorting)

      使用sort()方法,新生成的数据会替代原来的数据;

    二、复制排序(Copied sorting)

      保留原来的数据,然后新生成一个排序后的数据;

>>> data2=[6,3,1,2,4,5]
>>> data2
[6, 3, 1, 2, 4, 5]

>>> sorted(data2)
[1, 2, 3, 4, 5, 6]
>>> data2
[6, 3, 1, 2, 4, 5]
>>> data3=sorted(data2)
>>> data3
[1, 2, 3, 4, 5, 6]
>>> data1=[2,4,6,5,1,3]
>>> data1.sort()
>>> data1
[1, 2, 3, 4, 5, 6]

  使用print(sorted(data))来输出之前的james,julie,mikey,sarah列表,如下:

>>> print(sorted(james))
['2-22', '2-34', '2.34', '2.45', '2:01', '2:01', '3.01', '3:10', '3:21']
>>> print(sorted(julie))
['2-23', '2.11', '2.59', '2:11', '2:23', '3-10', '3-21', '3.21', '3:10']
>>> print(sorted(mikey))
['2.49', '2:22', '2:38', '3.01', '3.02', '3.02', '3:01', '3:02', '3:22']
>>> print(sorted(sarah))
['2-25', '2-55', '2.18', '2.58', '2:39', '2:54', '2:55', '2:55', '2:58']

  会发现,排序并不正确,目标是从左到右,从小到大。

  仔细看,发现有'-',':','.'这些符号,因为符号不统一,所以会影响排序。

  接下来,创建一个函数,名为:sanitize(),作用是:从各个选手的列表接收一个字符串,

  然后处理这个字符串,将找到的'-'和':'替换为'.'并返回清理过的字符串,此外如果字符串

  本身已经包含'.',那么就不需要在做清理工作了。

    函数代码如下:

>>> def sanitize(time_string):
    if'-'in time_string:
      splitter='-'
    elif ':'in time_string:
      splitter=':'
    else:
      return(time_string)
    (mins,secs)=time_string.split(splitter)
    return(mins+'.'+secs)

 

    实例二:接下来实现正确排序上面四个文件生成的列表

>>> with open('james.txt') as jaf:
    data = jaf.readline()
    james=data.strip().split(',')
    with open('julie.txt')as juf:
        data = juf.readline()
        julie=data.strip().split(',')
    with open('mikey.txt')as mif:
        data = mif.readline()
        mikey=data.strip().split(',')
    with open('sarah.txt')as saf:
        data = saf.readline()
        sarah=data.strip().split(',')
    clean_james=[]
    clean_julie=[]
    clean_mikey=[]
    clean_sarah=[]
    for each_t in james:
        clean_james.append(sanitize(each_t))
    for each_t in julie:
        clean_julie.append(sanitize(each_t))
    for each_t in mikey:
        clean_mikey.append(sanitize(each_t))
    for each_t in sarah:
        clean_sarah.append(sanitize(each_t))

        
>>> print(clean_james)
['2.34', '3.21', '2.34', '2.45', '3.01', '2.01', '2.01', '3.10', '2.22']
>>> print(clean_julie)
['2.59', '2.11', '2.11', '2.23', '3.10', '2.23', '3.10', '3.21', '3.21']
>>> print(clean_mikey)
['2.22', '3.01', '3.01', '3.02', '3.02', '3.02', '3.22', '2.49', '2.38']
>>> print(clean_sarah)
['2.58', '2.58', '2.39', '2.25', '2.55', '2.54', '2.18', '2.55', '2.55']
View Code

  重新排序如下: 

>>> print(sorted(clean_james))
['2.01', '2.01', '2.22', '2.34', '2.34', '2.45', '3.01', '3.10', '3.21']
>>> print(sorted(clean_julie))
['2.11', '2.11', '2.23', '2.23', '2.59', '3.10', '3.10', '3.21', '3.21']
>>> print(sorted(clean_mikey))
['2.22', '2.38', '2.49', '3.01', '3.01', '3.02', '3.02', '3.02', '3.22']
>>> print(sorted(clean_sarah))
['2.18', '2.25', '2.39', '2.54', '2.55', '2.55', '2.55', '2.58', '2.58']

  推导列表       

>>> print(sorted([sanitize(t)for t in james]))
['2.01', '2.01', '2.22', '2.34', '2.34', '2.45', '3.01', '3.10', '3.21']
>>> print(sorted([sanitize(t)for t in julie]))
['2.11', '2.11', '2.23', '2.23', '2.59', '3.10', '3.10', '3.21', '3.21']
>>> print(sorted([sanitize(t)for t in mikey]))
['2.22', '2.38', '2.49', '3.01', '3.01', '3.02', '3.02', '3.02', '3.22']
>>> print(sorted([sanitize(t)for t in sarah]))
['2.18', '2.25', '2.39', '2.54', '2.55', '2.55', '2.55', '2.58', '2.58']

   Python的列表推导是这种语言支持函数编程概念的一个例子。

   列表推导的妙处:通过使用列表推导可以大幅减少需要维护的代码。

   迭代删除重复项:

>>> unique_james=[]
>>> for each_t in james:
    if each_t not in unique_james:
      unique_james.append(each_t)

      >>> print(unique_james[0:3])
          ['2-34', '3:21', '2.34']

         通过not in操作符来滤除列表中的重复项。

  用集合删除重复项:

      通过set()可以创建一个新的集合,属于“工厂函数”,用于创建某种类型的新的数据项。  

  重新定义函数,精简代码,将数据返回代码前完成分解/去除空白符处理。

      

>>> unique_james=[]
>>> for each_t in james:
    if each_t not in unique_james:
        unique_james.append(each_t)

    
>>> print(unique_james[0:3])
['2-34', '3:21', '2.34']
>>> def get_coach_data(filename):
    try:
        with open(filename)as f:
            data=f.readline()
        return(data.strip().split(','))
    except IOError as ioerr:
        print('File error: '+ str(ioerr))
        return(None)

    
>>> sarah1 = get_coach_data('sarah.txt')
>>> print(sorted(set([sanitize(t)for t in james]))[0:3])
['2.01', '2.22', '2.34']
View Code

>>> print(sarah1)
['2:58', '2.58', '2:39', '2-25', '2-55', '2:54', '2.18', '2:55', '2:55']
>>> print(sorted(set([sanitize(t)for t in sarah1]))[0:3])
['2.18', '2.25', '2.39']

   函数串链:如 print(sorted(set([sanitize(t)for t in sarah1]))[0:3]),需要从右往左读,和方法串链正好相反。

   本质上是一堆函数的嵌套操作。

   总结

     Python术语:1原地排序:转换然后替换;

            2复制排序:转换然后返回;

            3方法串链:对数据应用一组方法;

            4函数串链:对数据应用一组函数;

            5列表推导:在一行上指定一个转换;

            6分片:从一个列表,访问多个列表项;

            7集合:一组无需的数据项,其中不包含重复项。

    具体方法:1 sort():原地排序;

         2 sorted():复制排序;

         3 对于以下代码:

           new=[]

          for t in old:

            new.append(len(t))

          可以用列表推导代替:new=[len(t) for t in old];

         4 分片:使用my_list[3:6]可以访问列表my_list从索引位置3到索引位置6的列表数据项;         

         5 使用set()工厂方法可以创建一个集合。

 

------------------------------------------------The End of Fifth Chapter------------------------------------------------

 

posted @ 2017-09-25 14:12  Blog_WHP  阅读(1243)  评论(0编辑  收藏  举报