python迭代

        如果给定一个list或者tuple,可以通过for循环来遍历这个list或tuple,这种遍历称为迭代(Iteration)。

        在python中,迭代是通过for...in来完成的,python的for循环不仅可以用在list或者tuple上,还可以作用在其他可迭代对象上。

        list这种数据类型虽然有下标,但很多其他数据类型是没有下标的,但是,只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代

1
2
3
4
5
6
7
>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> for key in d:
... print key
...
a
c
b

阅读全文 >>

python生成器

        通过列表生成式,可以直接创建一个list。但是受到内存限制,list容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

        所以,如果list元素可以按照某种算法推算出来,那就可以在循环的过程中不断推算出后续的元素。这样就不必创建完整的list,从而节省大量的空间。在python中,这种一边循环一边计算的机制,称为生成器(Generator)。

        要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator

1
2
3
4
5
6
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x104feab40>

阅读全文 >>

python列表生成式

        列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

        例:要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用range(1, 11)

1
2
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

        但如果要生成[1×1, 2×2, 3×3, …, 10×10]

        方法一

1
2
3
4
5
6
>>> L = []
>>> for x in range(1, 11):
... L.append(x * x)
...
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

阅读全文 >>

python匿名函数

        在传入函数时,有些时候,不需要显示定义函数,直接传入匿名函数更方便。

        在python中,对匿名函数提供了有限支持。还是以map()函数为例,计算f(x)=x^2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数

1
2
>>> map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]

        通过对比可以看出,匿名函数lambda x: x * x实际上就是

1
2
def f(x):
return x * x

阅读全文 >>

python高阶函数

        高阶函数引文叫Higher-order function。高阶函数就是把函数当成参数传递的一种函数。

  1. 变量可以指向函数

        以python内置的求绝对值的函数abs()为例,调用该函数

1
2
abs(-10)
10

        如果只写abs

1
2
abs
<built-in function abs>

        可见,abs(-10)是函数调用,而abs是函数本身。

阅读全文 >>

函数的参数

        Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。

        在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

  • 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。

  • 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

        python 函数的参数传递:

  • 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

  • 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

阅读全文 >>

python定义函数

        函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

        函数能提高应用的模块性,和代码的重复利用率。Python提供了许多内建函数,比如print()。但也可以自己创建函数,这被叫做用户自定义函数。

定义一个函数

        可以定义一个由自己想要功能的函数,规则如下

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
  • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
    函数内容以冒号起始,并且缩进。
  • return [表达式]结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

阅读全文 >>

瓜子云的任务调度系统

        瓜子云的任务调度系统结合了K8S的Job和Airflow。

        Airflow是Airbnb出品的任务调度系统,支持DAG调度,这一点完美的弥补了k8s Job的不足。借助k8s的自动扩展,集群资源统一管理,Airflow将更具灵活性,更稳定。但是,把Airflow部署在K8S上是一个很大的挑战。

        接下来详细介绍一下瓜子云的任务调度系统搭建所遇到的问题和解决方案。

        需求

        瓜子最早的时候,任务调度用的是 crontab,后来由于数据仓库的复杂调度需求,我们引入了Airflow。Airflow支持DAG依赖,失败重试,历史状态记录,log收集等多种非常使用的功能。

        Airflow有很多问题:

  • Airflow的worker需要手动搭建,可扩展性不好。
  • Job代码更新之后,需要手动部署到worker上,非常繁琐。
  • Airflow worker的环境太多,由各个团队自行维护,维护成本太高。
  • 瓜子云平台搭建之后,所有机器都会被回收,各业务线拥有的机器将会很少,worker将会没有地方部署。

阅读全文 >>

python raw_input

        条件判断中,会用raw_input()读取用户的输入,这样可以自己输入,程序运行的更有意思

1
2
3
4
5
birth = raw_input('birth: ')
if birth < 2000:
print '00前'
else:
print '00后'

        输入1982,结果却显示00后,这么简单的判断python为什么会出错?

        当然不是python的问题,在python的交互式命令下打印birth

1
2
3
4
5
6
>>> birth
'1982'
>>> '1982' < 2000
False
>>> 1982 < 2000
True

阅读全文 >>