python 常见细节知识点

1. a[::-1]翻转

设有一个元组或者列表

a = (1,2,3,4)
b = [1,2,3,4]

则a[::-1]和b[::-1]的含义是将元组或列表的内容翻转

a[::-1]  # 结果为(4,3,2,1)
b[::-1]  #结果为[4,3,2,1]

注意和a[:-1]的区别

a[:-1]表示从元组中切片,默认从第一个元素开始,到倒数第一个元素前面的那个元素为止

a[:-1] #结果为(1,2,3)
b[:-1] #结果为[1,2,3]

列表赋值y = x 相当于 指针传递;y = x[:]相当于 值传递

>>> a=[1,2,3,4,5,6,7,8,9]
>>> print(a[::2])
[1, 3, 5, 7, 9]

2.Python中a和a[:]有什么区别?

[]是引用 传址调用
[:] 是复制 传值调用

发现用b=a[:], 再给b赋值, 不会影响a; 直接给a[:]赋值却会影响a

a=5

b=a

print(a,b)

b=3

print(a,b)

a=6

print(a,b)

5 5
5 3
6 3

c=[1,2,3,4]

d=c

print(c,d)

c[0]=5

print(c,d)

d[0]=6

print(c,d)

[1, 2, 3, 4] [1, 2, 3, 4]
[5, 2, 3, 4] [5, 2, 3, 4]
[6, 2, 3, 4] [6, 2, 3, 4]

c=[1,2,3,4]

d=c[:]

print(c,d)

c[0]=5

print(c,d)

d[0]=6

print(c,d)

[1, 2, 3, 4] [1, 2, 3, 4]
[5, 2, 3, 4] [1, 2, 3, 4]
[5, 2, 3, 4] [6, 2, 3, 4]

c=[1,2,[1,2,3],3,4]

d=c[:] #  没有限制条件的分片表达式(L[:])能够复制序列,但此法只能浅层复制; 在有嵌套情况跟着一起变化

print(c,d)

c[0]=5

c[2][0]=7

print(c,d)

d[0]=6

print(c,d)

[1, 2, [1, 2, 3], 3, 4] [1, 2, [1, 2, 3], 3, 4]
[5, 2, [7, 2, 3], 3, 4] [1, 2, [7, 2, 3], 3, 4]
[5, 2, [7, 2, 3], 3, 4] [6, 2, [7, 2, 3], 3, 4]

import copy

c=[1,2,3,4]

d=copy.deepcopy(c)

print(c,d)

c[0]=5

print(c,d)

d[0]=6

print(c,d)

[1, 2, 3, 4] [1, 2, 3, 4]
[5, 2, 3, 4] [1, 2, 3, 4]
[5, 2, 3, 4] [6, 2, 3, 4]

a = [0, [1, 2], 3]

b = a[:]

a[0] = 8

a[1][1] = 9

print(a,b)

[8, [1, 9], 3] [0, [1, 9], 3]

import copy

a = [0, [1, 2], 3]

b = copy.deepcopy(a)

a[0] = 8

a[1][1] = 9

print(a,b)

[8, [1, 9], 3] [0, [1, 2], 3]

3.Python中flatten,matrix.A用法

一、用在数组

  1. >>> a = [[1,3],[2,4],[3,5]]  
  2. >>> a = array(a)  
  3. >>> a.flatten()  
  4. array([1, 3, 2, 4, 3, 5]) 

二、用在列表

如果直接用flatten函数会出错

  1. >>> a = [[1,3],[2,4],[3,5]]  
  2. >>> a.flatten()  
  3.   
  4. Traceback (most recent call last):  
  5.   File "<pyshell#10>", line 1, in <module>  
  6.     a.flatten()  
  7. AttributeError: 'list' object has no attribute 'flatten'  

正确的用法

  1. >>> a = [[1,3],[2,4],[3,5],["abc","def"]]  
  2. >>> a1 = [y for x in a for y in x]  
  3. >>> a1  
  4. [1, 3, 2, 4, 3, 5, 'abc', 'def']  

或者(不理解)

  1. >>> a = [[1,3],[2,4],[3,5],["abc","def"]]  
  2. >>> flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]  
  3. >>> flatten(a)  
  4. [1, 3, 2, 4, 3, 5, 'abc', 'def']  

三、用在矩阵

  1. >>> a = [[1,3],[2,4],[3,5]]  
  2. >>> a = mat(a)  
  3. >>> y = a.flatten()  
  4. >>> y  
  5. matrix([[1, 3, 2, 4, 3, 5]])  
  6. >>> y = a.flatten().A  
  7. >>> y  
  8. array([[1, 3, 2, 4, 3, 5]])  
  9. >>> shape(y)  
  10. (1, 6)  
  11. >>> shape(y[0])  
  12. (6,)  
  13. >>> y = a.flatten().A[0]  
  14. >>> y  
  15. array([1, 3, 2, 4, 3, 5]) 

 4.numpy.ravel() vs numpy.flatten()

首先声明两者所要实现的功能是一致的(将多维数组降位一维),两者的区别在于返回拷贝(copy)还是返回视图(view),numpy.flatten()返回一份拷贝,对拷贝所做的修改不会影响(reflects)原始矩阵,而numpy.ravel()返回的是视图(view,也颇有几分C/C++引用reference的意味),会影响(reflects)原始矩阵。

1. 两者的功能

>>> x = np.array([[1, 2], [3, 4]])
>>> x
array([[1, 2],
       [3, 4]])
>>> x.flatten()
array([1, 2, 3, 4])
>>> x.ravel()
array([1, 2, 3, 4])
                    两者默认均是行序优先
>>> x.flatten('F')
array([1, 3, 2, 4])
>>> x.ravel('F')
array([1, 3, 2, 4])

>>> x.reshape(-1)
array([1, 2, 3, 4])
>>> x.T.reshape(-1)
array([1, 3, 2, 4])

2. 两者的区别

>>> x = np.array([[1, 2], [3, 4]])
>>> x.flatten()[1] = 100
>>> x
array([[1, 2],
       [3, 4]])            # flatten:返回的是拷贝
>>> x.ravel()[1] = 100
>>> x
array([[  1, 100],
       [  3,   4]])

#coding:utf-8
import numpy as np

arr = np.arange(15).reshape(3, 5)
print arr
print arr.T #转制
print np.dot(arr, arr.T) #矩阵乘法

print '*' * 50

arr = np.arange(16).reshape((2,2,4))
# [[[ 0  1  2  3]
#   [ 4  5  6  7]] 
# 
#  [[ 8  9 10 11]
#   [12 13 14 15]]]
print arr[0] #二维数组
# [[0 1 2 3]
#  [4 5 6 7]]

print arr[0][0] #[0 1 2 3]
print arr[0, 0] #[0 1 2 3] 
print arr[[0],[0]] #[[0 1 2 3]]
print arr[0][0][0] #0

print arr.transpose((1,0,2)) 
# - a[0][0] = [0, 1, 2, 3]
# - a[0][1] = [4, 5, 6, 7]
# - a[1][0] = [8, 9, 10, 11]
# - a[1][1] = [12, 13, 14, 15]
# transpose的参数为坐标,正常顺序为(0, 1, 2, ... , n - 1),
# 现在传入的为(1, 0, 2)代表a[x][y][z] = a[y][x][z],第0个和第1个坐标互换。
# - a'[0][0] = a[0][0] = [0, 1, 2, 3]
# - a'[0][1] = a[1][0] = [8, 9, 10, 11]
# - a'[1][0] = a[0][1] = [4, 5, 6, 7]
# - a'[1][1] = a[1][1] = [12, 13, 14, 15]
# so,
# a'=
# [[[ 0  1  2  3]
#   [ 8  9 10 11]]
# 
#  [[ 4  5  6  7]
#   [12 13 14 15]]]

- 数组和元组之间的区别:数组内容是可以被修改的,而元组内容是只读的。
- Python自带的数据结构分为可变的和不可变的。可变的有:数组、集合、字典;不可变的有:字符串、元组、数。

1、python遍历文件夹
首先介绍python下的 glob 模块:可以很方便的在进行图像批处理时遍历文件夹下所有图像。

#coding:utf-8
import glob as gb    #导入glob模块
import cv2

# 返回该路径下所有的 jpg 文件的路径
img_path = gb.glob("/Users/steven/PycharmProjects/AI/RPN/*.jpg")
    for path in img_path:
        img = cv2.imread(path)
       # 处理图像
        cv2.imshow("img", img)
        cv2.waitKey(1000)

这样就实现了文件夹下指定类型文件的遍历。但仅仅实现遍历功能一般并不能满足我们的要求,我们可能需要对一个文件夹下的图像批进行处理,再将处理后的图像按照原来的名称保存在另一个文件夹下,这时我们就需要用到分离文件目录的操、文件名、文件后缀的操作。

2、文件目录、文件名及文件后缀的分离及合并
在python下对文件目录和文件名进行分离和合并,可以借助 os 模块来轻松搞定。

#文件目录、文件名及文件后缀的分离
import os
file_path = "/Users/steven/PycharmProjects/AI/RPN/3425581_0.jpg"
(filepath,tempfilename) = os.path.split(file_path)
(filename,extension) = os.path.splitext(tempfilename)

filepath:文件的目录,即 /Users/steven/PycharmProjects/AI/RPN/
tempfilename:文件的全名,即 3425581_0.jpg
filename:文件的名字,即 3425581_0
extension:文件的扩展名,即 .jpg

#文件目录及文件名的合并
import os
img_savepath = "/Users/steven/PycharmProjects/AI/RPN/ROIS"
savepath = os.path.join(img_savepath, tempfilename)

savepath:处理后文件保存的完整路径
img_ savepath:处理后文件保存的目录文件夹名称
tempfilename:待保存的文件的全名

- 2017 Python最新面试题及答案16道题

f-strings

要使用f-strings,只需在字符串前加上f,语法格式如下:

f ' <text> { <expression> <optional !s, !r, or !a> <optional : format specifier> } <text> ... '

基本用法

>>> name = "Tom"
>>> age = 3
>>> f"His name is {name}, he's {age} years old."
>>> "His name is Tom, he's 3 years old."

支持表达式

# 数学运算
>>> f'He will be { age+1 } years old next year.'
>>> 'He will be 4 years old next year.'

# 对象操作
>>> spurs = {"Guard": "Parker", "Forward": "Duncan"}
>>> f"The {len(spurs)} players are: {spurs['Guard']} the guard, and {spurs['Forward']} the forward."
>>> 'The 2 players are: Parker the guard, and Duncan the forward.'

>>> f'Numbers from 1-10 are {[_ for _ in range(1, 11)]}'
>>> 'Numbers from 1-10 are [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]'


原始字符串操作符( r/R )

是为了对付那些在字符串中出现的特殊字符(下面的小节会介绍这些特殊字符)。在原始字符串里,所有的字符都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。
除了原始字符串符号(引号前面的字母"r")以外,原始字符串跟普通字符串有着几乎完全相同的语法. 这个'r'可以是小写也可以是大写,唯一的要求是必须紧靠在第一个引号前.
原文地址:https://www.cnblogs.com/ranjiewen/p/7746537.html