面试题

试题1:

 程序如下:

 1 def extend_list(v, li=[]):
 2     li.append(v)
 3     return li
 4 
 5 list1 = extend_list(10)
 6 print(list1)  # [10, ]
 7 list2 = extend_list(123, [])
 8 list3 = extend_list('a')
 9 
10 print(list1)  # [10, a]
11 print(list2)  # [123]
12 print(list3)  # [10, a]
13 
14 print(list1 is list3)

 

 结果:

1 [10]
2 [10, 'a']
3 [123]
4 [10, 'a']
5 True

 

 分析:

  list1与list3的结果一样是由于这两个列表指向的是同个内存地址,另外程序是全部加载执行,等待全部程序执行完毕以后才打印结果.所以这两个列表的结果一样.

试题2:

问以下代码的输出结果是什么?
list1 = ["a", "b", "c", "d", "e"]
print(list1[10:])
程序如下:
1 list1 = ["a", "b", "c", "d", "e"]
2 print(list1[10:])

 

结果如下:

1 []

 

分析:

  列表切片,按照设置的索引参数去切,切不到返回空列表.

 

试题3:

如何打乱一个有序的列表?
代码如下:
1 list1 = [11, 22, 33, 44, 55]
2 import random
3 random.shuffle(list1)
4 print(list1)

 

 结果:

[11, 33, 44, 55, 22]

 

备注:

  因为打乱操作时随机的,所以每次运行的结果都不一样.

 

试题4:

  如何翻转一个列表?

    结果一:

1 list1 = [11, 22, 33, 44, 55]
2 list1.reverse()
3 print(list1)

 

    代码运行结果如下:

1 [55, 44, 33, 22, 11]

 

试题5:

 编写Python脚本,分析xx.log文件,按域名统计访问次数

xx.log文件内容如下:
https://www.sogo.com/ale.html
https://www.qq.com/3asd.html
https://www.sogo.com/teoans.html
https://www.bilibili.com/2
https://www.sogo.com/asd_sa.html
https://y.qq.com/
https://www.bilibili.com/1
https://dig.chouti.com/
https://www.bilibili.com/imd.html
https://www.bilibili.com/

脚本输出:
www.bilibili.com
www.sogo.com
1 www.qq.com
y.qq.com
dig.chouti.com
答案:
 1 import re
 2 import operator
 3 
 4 result = []
 5 dic = {}
 6 
 7 with open('xx.log', encoding='utf-8', mode='r') as f:
 8 
 9     for line in f:
10         ret = re.search('//.+/', line).group().strip('/')
11         result.append(ret)
12         num = result.count(ret)
13         dic[ret] =num
14 
15 ret = sorted(dic.items(), key=operator.itemgetter(1), reverse=True)
16 
17 for tup in ret:
18 
19     print(tup[1], tup[0])
答案

 

试题6:

os和sys都是干什么的?
  os模块与操作系统交互的一个接口.
  常用方法:

     拼接路径. Win路径分隔符:\  Unix(包含linux和ios)路径分隔符:/

    os.path.join('a', 'b')  # 将路径a与路径b拼接起来,a在前,b在后。

    os.path.sep / os.sep  # 获取当前操作系统的路径分隔符。

    os.path.abspath(__file__)  # 获取当前文件的绝对路径。

    os.path.dirname(path)  # 获取当前路径文件的目录。

    os.path.exists('文件的路径')  # 判断文件是否存在。

    os.path.getsize('文件路径')  # 获取当前文件的大小。

    os.mkdir('文件路径')  # 生成单级目录,也就是创建一个文件夹。

 

  sys模块是与paython解释器交互的一个接口。

  常用方法:

    sys.path  # 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值。

    sys.modules  # 获取Python解释器加载的所有模块。

    sys.argv  # 命令行参数List,第一个元素是程序本身路径。

    sys.exit()  # 退出程序,正常退出时exit(0),错误退出sys.exit(1)。

 

试题7:

  你工作中都用过哪些内置模块?

    time、re、json、hashlib、random、socket、collection、functools

 

试题8:

  列举collections模块的常用方法。

    在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

    1. namedtuple: 生成可以使用名字来访问元素内容的tuple。

    2. deque:双端队列,可以快速的从另外一侧追加和推出对象。

    3. Counter:计数器,主要用来计数。

    4. OrderedDict:有序字典。

    5.defaultdict:带有默认值的字典。

  namedtuple

    我们知道tuple可以表示不变集合,例如。一个点的二维坐标就可以表示成:

p = (1, 2)

    但是,看到(1,2),很难看出tuple是用来表示一个坐标的。

    这时,namedtuple就派上用场了:

from collections import namedtuple

Point = namedtuple('Point',['x', 'y'])
p = Point(1, 2)

print(p.x)
>>> 1
print(p.y)
>>> 2

    类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:

# namedtuple(‘名称’, [属性list]):
Cricle = namedtuple('Cricle', ['x', 'y', 'r'])

  deque

    使用list存储数据时,按索引访问 元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低.

    deque是为了高效实现插入和删除操作的双向列表,适用于队列和栈.

from collections import deque

q = deque(['a', 'b', 'c'])  # 将列表转化成双端队列
q.append('x')  # 在双端队列的右边添加一个元素
q.appendleft('y')  # 在双端队列的左边添加一个元素
print(q)
>>> deque(['y', 'a', 'b', 'c', 'x'])

    deque除了实现list的append()和pop()之外,还支持appendleft()和popleft(),这样就可以非常高效的往头部添加或删除元素.

  OrderedDict

    使用dict时,key是无序的.在对dict做迭代时,我们无法确定key的顺序.

    如果要保持key的顺序,可以用OrderedDict:

from collections import OrderedDict

d = dict([('a', 1), ('b', 2), ('c', 3)])  # 创建普通字典
print(d)
>>> {'a': 1, 'b': 2, 'c': 3}
od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])  # 创建有序字典
print(od)
>>> OrderedDict([('a', 1), ('b', 2), ('c', 3)])

 

    OrderedDict的key是有序的,他会按照插入的顺序排序,而不是key本身排序:

from collections import OrderedDict

od = OrderedDict()
od['z'] = 1
od['y'] = 2
od['x'] = 3
print(od.keys())  # 按照插入的key的顺序返回
>>> odict_keys(['z', 'y', 'x'])

 

  defaultdict

    有如下集合[11, 22, 33, 44, 55, 66, 77, 88, 99...],将所有大于66的值保存至字典的第一个key中,将所有大于66的值保存至字典的第一个key中,将小于66的保存至第二个key的值中.

即: {'k1': 大于66, 'k2': 小于66}

values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict  ={}

for value in values:
    
    if value > 66:

        if my_dict.__contains__('k1'):  # __contains__('key') 判断key存在与否,不存在就返回False,存在就返回True.
            my_dict['k1'].append(value)
        else:
            my_dict['k1'] = [value]

    else:

        if my_dict.__contains__('k2'):
            my_dict['k2'].append(value)
        else:
            my_dict['k2'] = [value]

print(my_dict)
>>> {'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]}

  使用defaultdict 字典解决方案:

from collections import defaultdict

values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = defaultdict(list)

for value in values:
    
    if value > 66:
        my_dict['k1'].append(value)
    else:
        my_dict['k2'].append(value)

print(my_dict)
>>> defaultdict(<class 'list'>, {'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]})

  使用dict时,如果引用的key不存在,就会抛出keyError.如果希望key不存在时,返回一个默认值,就可以用defaultdict:

from collections import defaultdict

dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'
print(dd['key1'])
>>> abc
print(dd['key2'])
>>> N/A

  Counter

    Counter类的目的是用来跟踪值出现的次数.他是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value.计数值可以是任意的Interger(包括0和负数).Counter类和其他语言的bags或multisets很相似.

from collections import Counter

c = Counter('abcdeabcdabcaba')

print(c)
>>> Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})

 

posted @ 2018-09-04 16:05  AKA绒滑服贵  阅读(129)  评论(0编辑  收藏  举报