In [2]:
import requests

cookies = {
    'qgqp_b_id': '604c2a463df1ad31917a5ed879c7aaa5',
    'st_pvi': '83022759114111',
    'st_sp': '2024-06-07%2009%3A57%3A49',
    'st_inirUrl': '',
    '6c17219c5c41be272e96f3ee1d4aaa02': 'RDMwRkMwODA4MzgxNDZCM0U4RTE5MzJCNUFCRDA5RjFFQURFQkQzNTY4MjMwMTI5NTYzRkU0NTI5MjQxQ0I5RA==',
    'pub_ticket': 'adb5af1e-9b29-409c-bc2b-3c84958af51c',
    'pub_empId': '210891',
    'CAS_badge': '210891',
    'CAS_name': '%E6%A2%81%E5%BE%B7%E8%83%9C',
    'st_si': '49372505290853',
    'st_sn': '12',
    'st_psi': '20240607123213316-111000300841-2594678295',
    'st_asi': 'delete',
    'token': '210891',
    'ems-tax-security': 'df80e794-7976-47c3-a071-e81529e7e811',
}

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0',
    'Accept': 'application/json, text/plain, */*',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding': 'gzip, deflate, br, zstd',
    'token': '210891',
    'Connection': 'keep-alive',
    'Referer': 'https://oa-pan-dev.eastmoney.com/tax/securitytaxmgr/taxPayersInfo',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',
    'Priority': 'u=0',
    'Pragma': 'no-cache',
    'Cache-Control': 'no-cache',
}

params = (
    ('pageNum', '1'),
    ('pageSize', '500'),
    ('total', '214'),
)

response = requests.get('https://oa-pan-dev.eastmoney.com/tax/securitytax/api/managementreport/taxpayerbaseinfo/queryPage', headers=headers, params=params, cookies=cookies)

#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.get('https://oa-pan-dev.eastmoney.com/tax/securitytax/api/managementreport/taxpayerbaseinfo/queryPage?pageNum=1&pageSize=10&total=214', headers=headers, cookies=cookies)
In [5]:
baseinfo = response.json()["data"]
In [6]:
import requests

cookies = {
    'qgqp_b_id': '604c2a463df1ad31917a5ed879c7aaa5',
    'st_pvi': '83022759114111',
    'st_sp': '2024-06-07%2009%3A57%3A49',
    'st_inirUrl': '',
    '6c17219c5c41be272e96f3ee1d4aaa02': 'RDMwRkMwODA4MzgxNDZCM0U4RTE5MzJCNUFCRDA5RjFFQURFQkQzNTY4MjMwMTI5NTYzRkU0NTI5MjQxQ0I5RA==',
    'pub_ticket': 'adb5af1e-9b29-409c-bc2b-3c84958af51c',
    'pub_empId': '210891',
    'CAS_badge': '210891',
    'CAS_name': '%E6%A2%81%E5%BE%B7%E8%83%9C',
    'st_si': '49372505290853',
    'st_sn': '12',
    'st_psi': '20240607123213316-111000300841-2594678295',
    'st_asi': 'delete',
    'token': '210891',
    'ems-tax-security': 'df80e794-7976-47c3-a071-e81529e7e811',
}

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0',
    'Accept': 'application/json, text/plain, */*',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding': 'gzip, deflate, br, zstd',
    'token': '210891',
    'Connection': 'keep-alive',
    'Referer': 'https://oa-pan-dev.eastmoney.com/tax/securitytaxmgr/basicInfo/taxPayer',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',
    'Priority': 'u=0',
    'Pragma': 'no-cache',
    'Cache-Control': 'no-cache',
}

params = (
    ('pageNum', '1'),
    ('pageSize', '300'),
    ('total', '256'),
)

response = requests.get('https://oa-pan-dev.eastmoney.com/tax/securitytax/api/system/taxpayer/get', headers=headers, params=params, cookies=cookies)

#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.get('https://oa-pan-dev.eastmoney.com/tax/securitytax/api/system/taxpayer/get?pageNum=1&pageSize=10&total=256', headers=headers, cookies=cookies)
In [9]:
taxpayers = response.json()["data"]
In [12]:
import pandas as pd 

baseinfo_df = pd.DataFrame(baseinfo)
taxpayers_df = pd.DataFrame(taxpayers)
In [19]:
bset = baseinfo_df['taxpayerNo']
tset = taxpayers_df['taxpayerNo']
In [44]:
print(dict(row))
{'accountType': 0.0, 'accountTypeName': '独立核算', 'accountingType': 110.0, 'accountingTypeName': '一般企业', 'actualTaxNo': '913100007714584745', 'bankAccount': '1001160609006941978', 'bankName': '中国工商银行上海市康健支行', 'businessCity': '310100000000', 'businessDistrict': '310104000000', 'businessProvince': '3', 'businessScope': '第二类增值电信业务中的呼叫中心业务和信息服务业务(以经营许可证为准),企业投资咨询、策划,商务咨询,会务会展咨询服务,计算机软硬件及网络系统的技术开发、技术服务、技术咨询、技术转让,设计、制作、发布、代理国内外各类广告,自有房屋租赁,计算机软件销售。', 'businessType': '股份有限公司(上市、自然人投资或控股)', 'companyCode': '101', 'companyName': '东财', 'competentTaxAuthority': '国家税务总局上海市嘉定区税务局第十五税务所', 'createTime': '2022-11-18 19:10:29', 'createUser': '1', 'creditRating': '0', 'creditRatingName': 'A', 'dataStatus': 1, 'dataStatusName': '正式', 'effectiveDate': '2005-01-20', 'id': '1593562281113935873', 'industryClassCode': 'I646496490', 'industryClassId': '1593589631303274496', 'industryClassName': '其他互联网服务', 'isBuildingTaxDeclare': nan, 'isCCFDeclare': nan, 'isDisabilityPensionDeclare': nan, 'isEnable': 0, 'isEnableName': '不启用', 'isEuityInvestmentBusiness': 1.0, 'isIncomeTaxPrepayment': nan, 'isIncomeTaxRemittance': nan, 'isLandTaxDeclare': nan, 'isLimitsProhibitsIndustries': 1.0, 'isListedCompany': 0.0, 'isNpo': 1.0, 'isOverseasChineseHolding': 1.0, 'isOverseasRegistered': 1.0, 'isOverseasTp': 1.0, 'isStampDutyDeclare': nan, 'isStampDutyProvision': nan, 'isSummaryCompany': 1.0, 'isVatDeclare': nan, 'isVatPrepayment': nan, 'isVatProvision': nan, 'isVirtualTaxNo': 1.0, 'leadingName': '其实', 'legalEntityTaxpayerName': '', 'legalEntityTaxpayerNo': '', 'listedType': 0.0, 'listedTypeName': '境内', 'parentName': '', 'parentTaxpayerNo': '', 'prepayMethod': 0.0, 'prepayMethodName': '实行据实预缴的纳税人', 'registerCity': '310100000000', 'registerDistrict': '310114000000', 'registerPostalCode': '201800', 'registerProvince': '3', 'taxCollectorContact': '021-69150599', 'taxCollectorName': '张艳', 'taxRegisterStatus': 10, 'taxRegisterStatusName': '正常', 'taxpayerAddress': '宛平南路88号', 'taxpayerName': '东方财富信息股份有限公司', 'taxpayerNo': '913100007714584745', 'taxpayerPhone': '021-54509977', 'taxpayerSource': '0', 'taxpayerSourceName': '', 'vatTaxpayerIdentity': 0, 'vatTaxpayerIdentityName': '一般纳税人'}
In [39]:
for it in taxpayers_df.iterrows():
    _, row = it
    if row['taxpayerNo'] != row['actualTaxNo']:
        print(dict(row))
{'accountType': nan, 'accountTypeName': '', 'accountingType': nan, 'accountingTypeName': '', 'actualTaxNo': '', 'bankAccount': '', 'bankName': '', 'businessCity': None, 'businessDistrict': None, 'businessProvince': None, 'businessScope': '', 'businessType': '', 'companyCode': '6000002', 'companyName': '东方财富证券那曲拉萨南路证券营业部', 'competentTaxAuthority': '', 'createTime': '2024-04-08 19:36:55', 'createUser': '1648225166079057920', 'creditRating': '', 'creditRatingName': '', 'dataStatus': 1, 'dataStatusName': '正式', 'effectiveDate': '2024-04-07', 'id': '1777299578629480448', 'industryClassCode': '', 'industryClassId': None, 'industryClassName': '', 'isBuildingTaxDeclare': nan, 'isCCFDeclare': nan, 'isDisabilityPensionDeclare': nan, 'isEnable': 1, 'isEnableName': '启用', 'isEuityInvestmentBusiness': nan, 'isIncomeTaxPrepayment': nan, 'isIncomeTaxRemittance': nan, 'isLandTaxDeclare': nan, 'isLimitsProhibitsIndustries': nan, 'isListedCompany': nan, 'isNpo': nan, 'isOverseasChineseHolding': nan, 'isOverseasRegistered': nan, 'isOverseasTp': nan, 'isStampDutyDeclare': nan, 'isStampDutyProvision': nan, 'isSummaryCompany': nan, 'isVatDeclare': nan, 'isVatPrepayment': nan, 'isVatProvision': nan, 'isVirtualTaxNo': nan, 'leadingName': '', 'legalEntityTaxpayerName': '', 'legalEntityTaxpayerNo': '', 'listedType': nan, 'listedTypeName': '', 'parentName': '东方财富证券股份有限公司', 'parentTaxpayerNo': '91540000710910420Y', 'prepayMethod': nan, 'prepayMethodName': '', 'registerCity': '540100000000', 'registerDistrict': '540101000000', 'registerPostalCode': '', 'registerProvince': '540000000000', 'taxCollectorContact': '', 'taxCollectorName': '', 'taxRegisterStatus': 10, 'taxRegisterStatusName': '正常', 'taxpayerAddress': '', 'taxpayerName': '东方财富证券股份有限公司那曲拉萨南路证券营业部', 'taxpayerNo': '91540602MAD4EAC12F', 'taxpayerPhone': '', 'taxpayerSource': '1', 'taxpayerSourceName': '证券', 'vatTaxpayerIdentity': 0, 'vatTaxpayerIdentityName': '一般纳税人'}
{'accountType': nan, 'accountTypeName': '', 'accountingType': nan, 'accountingTypeName': '', 'actualTaxNo': '', 'bankAccount': '', 'bankName': '', 'businessCity': None, 'businessDistrict': None, 'businessProvince': None, 'businessScope': '', 'businessType': '', 'companyCode': '25400', 'companyName': '', 'competentTaxAuthority': '', 'createTime': '2023-02-23 14:36:28', 'createUser': '1597891883281993728', 'creditRating': '', 'creditRatingName': '', 'dataStatus': 1, 'dataStatusName': '正式', 'effectiveDate': '2023-02-08', 'id': '1626395064311865344', 'industryClassCode': '', 'industryClassId': None, 'industryClassName': '', 'isBuildingTaxDeclare': 0.0, 'isCCFDeclare': 0.0, 'isDisabilityPensionDeclare': 1.0, 'isEnable': 0, 'isEnableName': '不启用', 'isEuityInvestmentBusiness': nan, 'isIncomeTaxPrepayment': nan, 'isIncomeTaxRemittance': 1.0, 'isLandTaxDeclare': 1.0, 'isLimitsProhibitsIndustries': nan, 'isListedCompany': nan, 'isNpo': nan, 'isOverseasChineseHolding': nan, 'isOverseasRegistered': nan, 'isOverseasTp': nan, 'isStampDutyDeclare': 0.0, 'isStampDutyProvision': 0.0, 'isSummaryCompany': nan, 'isVatDeclare': nan, 'isVatPrepayment': 0.0, 'isVatProvision': nan, 'isVirtualTaxNo': nan, 'leadingName': '', 'legalEntityTaxpayerName': '', 'legalEntityTaxpayerNo': '', 'listedType': nan, 'listedTypeName': '', 'parentName': '', 'parentTaxpayerNo': '', 'prepayMethod': nan, 'prepayMethodName': '', 'registerCity': None, 'registerDistrict': None, 'registerPostalCode': '', 'registerProvince': None, 'taxCollectorContact': '', 'taxCollectorName': '', 'taxRegisterStatus': 10, 'taxRegisterStatusName': '正常', 'taxpayerAddress': '', 'taxpayerName': '测试2', 'taxpayerNo': '369', 'taxpayerPhone': '', 'taxpayerSource': '', 'taxpayerSourceName': '', 'vatTaxpayerIdentity': 0, 'vatTaxpayerIdentityName': '一般纳税人'}
{'accountType': nan, 'accountTypeName': '', 'accountingType': nan, 'accountingTypeName': '', 'actualTaxNo': '', 'bankAccount': '', 'bankName': '', 'businessCity': None, 'businessDistrict': None, 'businessProvince': None, 'businessScope': '', 'businessType': '', 'companyCode': '2350102', 'companyName': '', 'competentTaxAuthority': '', 'createTime': '2023-02-23 14:36:20', 'createUser': '1597891883281993728', 'creditRating': '', 'creditRatingName': '', 'dataStatus': 1, 'dataStatusName': '正式', 'effectiveDate': '2022-12-23', 'id': '1628644911836307456', 'industryClassCode': '', 'industryClassId': None, 'industryClassName': '', 'isBuildingTaxDeclare': nan, 'isCCFDeclare': nan, 'isDisabilityPensionDeclare': nan, 'isEnable': 0, 'isEnableName': '不启用', 'isEuityInvestmentBusiness': nan, 'isIncomeTaxPrepayment': nan, 'isIncomeTaxRemittance': nan, 'isLandTaxDeclare': nan, 'isLimitsProhibitsIndustries': nan, 'isListedCompany': nan, 'isNpo': 1.0, 'isOverseasChineseHolding': nan, 'isOverseasRegistered': nan, 'isOverseasTp': nan, 'isStampDutyDeclare': nan, 'isStampDutyProvision': nan, 'isSummaryCompany': nan, 'isVatDeclare': nan, 'isVatPrepayment': nan, 'isVatProvision': nan, 'isVirtualTaxNo': nan, 'leadingName': '', 'legalEntityTaxpayerName': '', 'legalEntityTaxpayerNo': '', 'listedType': nan, 'listedTypeName': '', 'parentName': '', 'parentTaxpayerNo': '', 'prepayMethod': nan, 'prepayMethodName': '', 'registerCity': None, 'registerDistrict': None, 'registerPostalCode': '', 'registerProvince': None, 'taxCollectorContact': '', 'taxCollectorName': '', 'taxRegisterStatus': 10, 'taxRegisterStatusName': '正常', 'taxpayerAddress': '', 'taxpayerName': '2222', 'taxpayerNo': '22222', 'taxpayerPhone': '', 'taxpayerSource': '', 'taxpayerSourceName': '', 'vatTaxpayerIdentity': 0, 'vatTaxpayerIdentityName': '一般纳税人'}
In [50]:
taxpayers_df.query("taxpayerNo not in @bset").reset_index()
Out[50]:
index accountType accountTypeName accountingType accountingTypeName actualTaxNo bankAccount bankName businessCity businessDistrict ... taxRegisterStatus taxRegisterStatusName taxpayerAddress taxpayerName taxpayerNo taxpayerPhone taxpayerSource taxpayerSourceName vatTaxpayerIdentity vatTaxpayerIdentityName
0 5 0.0 独立核算 110.0 一般企业 91310000682253629E ‘1001160609006986786 中国工商银行股份有限公司上海市康健支行 310100000000 310104000000 ... 10 正常 上海市徐汇区龙田路190号2号楼二层 上海天天基金销售有限公司 91310000682253629E 021-54509977-8399 0 0 一般纳税人
1 7 0.0 独立核算 130.0 证券 91410100MA449PR07D 16001301040011349 农业银行郑州未来支行 410100000000 410105000000 ... 10 正常 郑州市金水区未来路69号未来大厦1709房间 上海东方财富期货有限公司河南分公司 91410100MA449PR07D 13837181310 2 期货 0 一般纳税人
2 8 0.0 独立核算 130.0 证券 912102043967080201 212060120018010026090 交通银行大连商品交易所支行 210200000000 210204000000 ... 10 正常 大连市沙河口区会展路129号大连期货大厦3206室 上海东方财富期货有限公司大连分公司 912102043967080201 0411-84807911 2 期货 0 一般纳税人
3 9 0.0 独立核算 130.0 证券 91540000585798491J 54001023936052500992 建设银行拉萨柳梧支行 540100000000 540175000000 ... 10 正常 拉萨柳梧新区东环路以西、1-4路以北、1-3路以南、柳梧大厦以东10栋1单元1层1号104室... 上海东方财富期货有限公司拉萨营业部 91540000585798491J 0891-6803701 2 期货 0 一般纳税人
4 10 0.0 独立核算 130.0 证券 91310000729396054H 0764734292802839 浦发银行期交所支行 310100000000 310115000000 ... 10 正常 中国(上海)自由贸易试验区世纪大道1500号12楼北座、802A室、802B室、802D-3... 上海东方财富期货有限公司 91310000729396054H 021-60277028 2 期货 0 一般纳税人
5 232 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
6 233 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
7 234 0.0 独立核算 110.0 一般企业 91310000682253629E ‘1001160609006986786 中国工商银行股份有限公司上海市康健支行 310100000000 310104000000 ... 10 正常 上海市徐汇区龙田路190号2号楼二层 上海天天基金销售有限公司 91310000682253629E 021-54509977-8399 0 0 一般纳税人
8 235 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
9 236 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
10 237 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
11 238 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
12 239 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
13 240 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
14 241 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
15 242 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
16 243 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
17 244 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
18 245 NaN NaN None None ... 10 正常 测试2 369 0 一般纳税人
19 246 NaN NaN None None ... 10 正常 2222 22222 0 一般纳税人
20 247 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
21 248 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
22 249 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
23 250 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
24 251 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
25 252 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
26 253 0.0 独立核算 110.0 一般企业 91310000682253629E ‘1001160609006986786 中国工商银行股份有限公司上海市康健支行 310100000000 310104000000 ... 10 正常 上海市徐汇区龙田路190号2号楼二层 上海天天基金销售有限公司 91310000682253629E 021-54509977-8399 0 0 一般纳税人
27 254 0.0 独立核算 110.0 一般企业 91310000682253629E ‘1001160609006986786 中国工商银行股份有限公司上海市康健支行 310100000000 310104000000 ... 10 正常 上海市徐汇区龙田路190号2号楼二层 上海天天基金销售有限公司 91310000682253629E 021-54509977-8399 0 0 一般纳税人
28 255 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人

29 rows × 74 columns

In [49]:
len(taxpayers_df) - len(baseinfo_df)
Out[49]:
42
In [47]:
taxpayers_df.query('isEnableName != "启用"').reset_index()
Out[47]:
index accountType accountTypeName accountingType accountingTypeName actualTaxNo bankAccount bankName businessCity businessDistrict ... taxRegisterStatus taxRegisterStatusName taxpayerAddress taxpayerName taxpayerNo taxpayerPhone taxpayerSource taxpayerSourceName vatTaxpayerIdentity vatTaxpayerIdentityName
0 213 1.0 非独立核算 130.0 证券 91130100050962654X 101215354847 中国银行股份有限公司河北省分行 130100000000 130104000000 ... 10 正常 河北省石家庄市桥西区中山西路108号华润万象城01-1103、1104 东方财富证券股份有限公司石家庄中山西路证券营业部test 91130100050962654X 13903118199 0 一般纳税人
1 214 1.0 非独立核算 130.0 证券 91110108MA00CQNP4M 110927993010201 招商银行北京西直门支行 110100000000 110108000000 ... 10 正常 北京市海淀区西直门北大街32号院2号楼13层1506 东方财富证券股份有限公司北京分公司测试 91110108MA00CQNP4M 15801298857 0 一般纳税人
2 215 1.0 非独立核算 130.0 证券 91110108MA00CQNP4M 110927993010201 招商银行北京西直门支行 110100000000 110108000000 ... 10 正常 北京市海淀区西直门北大街32号院2号楼13层1506 东方财富证券股份有限公司北京分公司测试 91110108MA00CQNP4M 15801298857 0 一般纳税人
3 216 0.0 独立核算 130.0 证券 91540000710910420Y 25980001040013171 中国农业银行股份有限公司拉萨康昂东路支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10栋楼 东方财富证券股份有限公司 91540000710910420Y 010-6526100 0 一般纳税人
4 217 0.0 独立核算 130.0 证券 91540000397684980B 54001023936052502743 中国建设银行股份有限公司拉萨柳梧支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10号楼三层2室 西藏东方财富投资管理有限公司 91540000397684980B 021-23586442 1 小规模纳税人
5 218 0.0 独立核算 130.0 证券 91540000397684980B 54001023936052502743 中国建设银行股份有限公司拉萨柳梧支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10号楼三层2室 西藏东方财富投资管理有限公司 91540000397684980B 021-23586442 1 小规模纳税人
6 219 0.0 独立核算 130.0 证券 91540000397684980B 54001023936052502743 中国建设银行股份有限公司拉萨柳梧支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10号楼三层2室 西藏东方财富投资管理有限公司 91540000397684980B 021-23586442 1 小规模纳税人
7 220 0.0 独立核算 130.0 证券 91540195MA6TDXLL06 54050101363600002446 中国建设银行股份有限公司拉萨北京中路支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10栋楼 西藏东方财富创新资本有限公司 91540195MA6TDXLL06 021-23586442 1 小规模纳税人
8 221 0.0 独立核算 130.0 证券 91540195MA6TDXLL06 54050101363600002446 中国建设银行股份有限公司拉萨北京中路支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10栋楼 西藏东方财富创新资本有限公司 91540195MA6TDXLL06 021-23586442 1 小规模纳税人
9 222 0.0 独立核算 130.0 证券 91540195MA6TDXLL06 54050101363600002446 中国建设银行股份有限公司拉萨北京中路支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10栋楼 西藏东方财富创新资本有限公司 91540195MA6TDXLL06 021-23586442 1 小规模纳税人
10 223 0.0 独立核算 130.0 证券 91540195MA6TDXLL06 54050101363600002446 中国建设银行股份有限公司拉萨北京中路支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10栋楼 西藏东方财富创新资本有限公司 91540195MA6TDXLL06 021-23586442 1 小规模纳税人
11 224 0.0 独立核算 130.0 证券 91540195MA6TDXLL06 54050101363600002446 中国建设银行股份有限公司拉萨北京中路支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10栋楼 西藏东方财富创新资本有限公司 91540195MA6TDXLL06 021-23586442 1 小规模纳税人
12 225 0.0 独立核算 130.0 证券 91540195MA6TDXLL06 54050101363600002446 中国建设银行股份有限公司拉萨北京中路支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10栋楼 西藏东方财富创新资本有限公司 91540195MA6TDXLL06 021-23586442 1 小规模纳税人
13 226 0.0 独立核算 130.0 证券 91540000397684980B 54001023936052502743 中国建设银行股份有限公司拉萨柳梧支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10号楼三层2室 西藏东方财富投资管理有限公司 91540000397684980B 021-23586442 1 小规模纳税人
14 227 0.0 独立核算 130.0 证券 91540195MA6TDXLL06 54050101363600002446 中国建设银行股份有限公司拉萨北京中路支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10栋楼 西藏东方财富创新资本有限公司 91540195MA6TDXLL06 021-23586442 1 小规模纳税人
15 228 0.0 独立核算 130.0 证券 91540000710910420Y 25980001040013171 中国农业银行股份有限公司拉萨康昂东路支行 540100000000 1739528700054593536 ... 10 正常 拉萨市柳梧新区国际总部城10栋楼 东方财富证券股份有限公司 91540000710910420Y 010-6526100 0 一般纳税人
16 229 1.0 非独立核算 130.0 证券 91440605MA4W759H1C 44505701040000047 中国农业银行南海万达支行 440600000000 440605000000 ... 10 正常 佛山市南海区桂城街道融和路24号万科荟光大厦1栋714室 东方财富证券股份有限公司佛山融和路证券营业部 91440605MA4W759H1C 13826406577 0 一般纳税人
17 230 1.0 非独立核算 130.0 证券 91130100050962654X 101215354847 中国银行股份有限公司河北省分行 130100000000 130104000000 ... 10 正常 河北省石家庄市桥西区中山西路108号华润万象城01-1103、1104 东方财富证券股份有限公司石家庄中山西路证券营业部 91130100050962654X 13903118199 0 一般纳税人
18 231 1.0 非独立核算 130.0 证券 91110108MA00CQNP4M 110927993010201 招商银行北京西直门支行 110100000000 110108000000 ... 10 正常 北京市海淀区西直门北大街32号院2号楼13层1506 东方财富证券股份有限公司北京分公司 91110108MA00CQNP4M 15801298857 0 一般纳税人
19 232 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
20 233 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
21 234 0.0 独立核算 110.0 一般企业 91310000682253629E ‘1001160609006986786 中国工商银行股份有限公司上海市康健支行 310100000000 310104000000 ... 10 正常 上海市徐汇区龙田路190号2号楼二层 上海天天基金销售有限公司 91310000682253629E 021-54509977-8399 0 0 一般纳税人
22 235 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
23 236 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
24 237 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
25 238 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
26 239 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
27 240 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
28 241 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
29 242 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
30 243 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
31 244 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
32 245 NaN NaN None None ... 10 正常 测试2 369 0 一般纳税人
33 246 NaN NaN None None ... 10 正常 2222 22222 0 一般纳税人
34 247 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
35 248 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
36 249 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
37 250 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
38 251 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
39 252 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人
40 253 0.0 独立核算 110.0 一般企业 91310000682253629E ‘1001160609006986786 中国工商银行股份有限公司上海市康健支行 310100000000 310104000000 ... 10 正常 上海市徐汇区龙田路190号2号楼二层 上海天天基金销售有限公司 91310000682253629E 021-54509977-8399 0 0 一般纳税人
41 254 0.0 独立核算 110.0 一般企业 91310000682253629E ‘1001160609006986786 中国工商银行股份有限公司上海市康健支行 310100000000 310104000000 ... 10 正常 上海市徐汇区龙田路190号2号楼二层 上海天天基金销售有限公司 91310000682253629E 021-54509977-8399 0 0 一般纳税人
42 255 0.0 独立核算 110.0 一般企业 913100007714584745 1001160609006941978 中国工商银行上海市康健支行 310100000000 310104000000 ... 10 正常 宛平南路88号 东方财富信息股份有限公司 913100007714584745 021-54509977 0 0 一般纳税人

43 rows × 74 columns

常用函数, 定义,,,¶

In [2]:
from typing import List, Tuple, Dict, Optional


class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
  

def gen_linked_list(ls):
    head = ListNode(ls[0])
    p = head
    for item in ls[1:]:
        p.next = ListNode(item)
        p = p.next
    return head 

def print_linked_list(head, msg=None):
    ls = []
    while head:
        ls.append(head.val)
        head = head.next
    if msg:
        print(msg, ls)
    else:
        print(ls)
        

143. 重排链表¶

In [40]:
class Solution:
    def find_mid(self, head: ListNode):
        slow, fast = head, head
        while fast and fast.next:
            slow = slow.next # type: ignore
            fast = fast.next
            if fast:
                fast = fast.next
        return slow

    def reverse_linked_list(self, head: ListNode):
        p = head.next
        head.next = None
        while p:
            p_next = p.next
            temp = head.next
            head.next = p 
            p.next = temp
            p = p_next
    
    def reorderList(self, head: Optional[ListNode]) -> None:
        """
        Do not return anything, modify head in-place instead.
        """
        
        if not head:
            return head
        mid = self.find_mid(head)
        print_linked_list(mid, 'mid')
        dumb_node = ListNode(-1, mid)
        self.reverse_linked_list(dumb_node)
        mid = dumb_node.next
        print_linked_list(mid, 'mid')
        
        merge_node = ListNode(-1, None)
        part1 = head
        part2 = mid
        while part2:
            print_linked_list(part1, 'part1')
            print_linked_list(part2, 'part2')
            p1_next = part1.next
            p2_next = part2.next
            
            merge_node.next = part1
            part1.next = part2
            part2.next = None
            
            merge_node = part2
            part1 = p1_next
            part2 = p2_next
            
            print_linked_list(head, "head")
            print("=" * 10)


ls = [1, 2, 3, 4, 5, 6]
head = gen_linked_list(ls)

Solution().reorderList(head)
print_linked_list(head, "final")
mid [4, 5, 6]
mid [6, 5, 4]
part1 [1, 2, 3, 4]
part2 [6, 5, 4]
head [1, 6]
==========
part1 [2, 3, 4]
part2 [5, 4]
head [1, 6, 2, 5]
==========
part1 [3, 4]
part2 [4]
head [1, 6, 2, 5, 3, 4]
==========
final [1, 6, 2, 5, 3, 4]

144. 二叉树的前序遍历¶

In [ ]:
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        def walk(node):
            if not node:
                return 
            res.append(node.val)
            walk(node.left)
            walk(node.right)
        walk(root)
        return res

145. 二叉树的后序遍历¶

In [ ]:
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        def walk(node):
            if not node:
                return 
            walk(node.left)
            walk(node.right)
            res.append(node.val)
        walk(root)
        return res

146. LRU 缓存¶

In [100]:
print_flag = True

def print_linked_list(head, msg=None):
    ls = []
    while head:
        ls.append(head.val)
        head = head.next
    if msg:
        print(msg, ls)
    else:
        print(ls)
        
def log(method):
    def decorator(*args, **kwargs):
        if print_flag:
            print(method.__name__, "args", args[1:])
            # print(f"before【{method.__name__}】", list(args[0]._container.keys()))
            print_linked_list(args[0]._head)
        ret = method(*args, **kwargs)
        if print_flag:
            # print(f"after【{method.__name__}】", list(args[0]._container.keys()))
            print_linked_list(args[0]._head)
            print("=" * 30)
        return ret
    return decorator

class DLikedNode:
    def __init__(self, key, val=-1, pre=None, next=None):
        self.key = key
        self.val = val
        self.pre: Optional[DLikedNode] = pre
        self.next: Optional[DLikedNode] = next


class LRUCache:


    def __init__(self, capacity: int):
        self._container: Dict[int, DLikedNode] = dict()
        self._head = DLikedNode(-1)
        self._end = DLikedNode(-1)
        self._head.next = self._end
        self._end.pre = self._head
        self._capacity = capacity
        self._key_size = 0


    @log
    def _evit(self,):
        node = self._container.pop(self._end.pre.key)
        self._capacity -= 1
        pre, cur = node.pre, node
        self._cat(pre, cur.next)
    
    def _cat(self, pre, next):
        pre.next = next
        next.pre = pre

    @log
    def _move_to_head(self, key):
        node = self._container[key]
        pre, cur = node.pre, node
        self._cat(pre, cur.next)
        self._cat(cur, self._head.next)
        self._cat(self._head, cur)

    # @log
    def _add_node(self, key, value):
        head_next = self._head.next
        self._head.next = DLikedNode(key, value,  self._head, head_next)
        self._cat(self._head.next, head_next)
        self._container[key] = self._head.next

    def get(self, key: int) -> int:
        if key not in self._container:
            return -1
        else:
            self._move_to_head(key)
            return self._container[key].val

    def put(self, key: int, value: int) -> None:

        if key not in self._container:
            if self._key_size >= self._capacity:
                self._evit()
                self._add_node(key, value)
            else:
                self._key_size += 1
                self._add_node(key, value)
        else:
            self._container[key].val = value
            self._move_to_head(key)
            
        


ops = ["LRUCache","put","put","get","put","get","put","get","get","get"]
args = [[2],[1,0],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]]

lru = LRUCache(args[0][0])
ops = ops[1:]
args = args[1:]


ret = []
for i, op in enumerate(ops):
    if op == 'get':
        ret.append(lru.get(*args[i]))
    else:
        lru.put(*args[i])
print(ret)
_update args (1,)
[-1, 2, 0, -1]
[-1, 0, 2, -1]
==============================
_evit args (3, 3)
[-1, 0, 2, -1]
[-1, 3, 0, -1]
==============================
_evit args (4, 4)
[-1, 3, 0, -1]
[-1, 4, 3, -1]
==============================
_update args (3,)
[-1, 4, 3, -1]
[-1, 3, 4, -1]
==============================
_update args (4,)
[-1, 3, 4, -1]
[-1, 4, 3, -1]
==============================
[0, -1, -1, 3, 4]

147. 对链表进行插入排序¶

In [5]:
class Solution:
    def insertionSortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        def insert(cur_list: ListNode, todo: ListNode):
            todo.next = None
            pre, cur = cur_list, cur_list.next
            while cur:
                if todo.val < cur.val:
                    pre.next = todo
                    todo.next = cur
                    return 
                pre = cur
                cur = cur.next
            pre.next = todo
            
        if not head:
            return head
        p = head.next
        dummy_head = ListNode(-10000, head)
        head.next = None
        while p:
            p_next = p.next
            insert(dummy_head, p)
            p = p_next
        return dummy_head.next

print_linked_list(Solution().insertionSortList(gen_linked_list([4,2,1,3])))
[1, 2, 3, 4]

148. 排序链表¶

In [12]:
class Solution:
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        def merge(l1: ListNode, l2: ListNode):
            if l1 is None:
                return l2 
            elif l2 is None:
                return l1 
            else:
                if l1.val < l2.val:
                    p1, p2 = l1, l2 
                else:
                    p1, p2 = l2, l1 
                res = p1
                res_last = p1
                p1 = p1.next
                while p1 and p2:
                    if p1.val < p2.val:
                        res_last.next = p1 
                        res_last = p1
                        p1 = p1.next 
                    else:
                        res_last.next = p2
                        res_last = p2
                        p2 = p2.next
                if p1 is not None:
                    res_last.next = p1
                if p2 is not None:
                    res_last.next = p2
                return res
        
        def sort_fun(head: ListNode, tail:ListNode):
            if head == tail:
                head.next = None
                return head
            elif head.next == tail:
                head.next = None
                return head
            
            fast, slow = head, head 
            while fast and fast != tail:
                slow = slow.next
                fast = fast.next
                if fast and fast != tail:
                    fast = fast.next
            l1 = sort_fun(head, slow)
            l2 = sort_fun(slow, tail)
            
            return merge(l1, l2)
            
        if not head:
            return head
        
        return sort_fun(head, None)

print_linked_list(Solution().sortList(gen_linked_list([-1,0,3,4,5])))
[-1, 0, 3, 4, 5]

149. 直线上最多的点数¶

In [15]:
import sys

max_float_value = sys.float_info.max
print("Maximum float value:", max_float_value)
Maximum float value: 1.7976931348623157e+308
In [ ]:
from collections import defaultdict
def gcd(a, b):
    return gcd(b, a % b) if (b != 0) else a

class Solution:
    def maxPoints(self, points: List[List[int]]) -> int:
        if len(points) == 1:
            return 1

        def get_b(dy, dx, y, x):
            return y - dy * x / dx 
            
        def grad(p1, p2):
            x1, y1 = p1
            x2, y2 = p2
            
            dy = y2 - y1
            dx = x2 - x1 
            
            if dx  == 0:
                return (1, 0, x1)
            elif dy == 0:
                return (0, 1, y1)
            
            d = gcd(abs(dy) , abs(dx))
            dy /= d
            dx /= d
            
            if dy * dx < 0:
                dy = abs(dy)
                dx = -abs(dx)
            
            
            return  dy, dx, get_b(dy, dx, y1, x1)
        
        counter = defaultdict(set)
        for i, point1 in enumerate(points):
            for j in range(i+1, len(points)):
                point2 = points[j]
                # counter[grad(point1, point2)] += 1
                counter[grad(point1, point2)].add(tuple(point1))
                counter[grad(point1, point2)].add(tuple(point2))
        return max(map(lambda it: len(it[-1]), counter.items()))
In [ ]:
y = ax + b 
a = dy / dx 
b = y - dy/dx*x
In [35]:
def gcd(a, b):
    return gcd(b, a % b) if (b != 0) else a

class Solution:
    def maxPoints(self, points: List[List[int]]) -> int:
        if len(points) == 1:
            return 1
            
        def grad(p1, p2):
            x1, y1 = p1
            x2, y2 = p2
            
            dy = y2 - y1
            dx = x2 - x1 
            
            if dx  == 0:
                return (1, 0)
            elif dy == 0:
                return (0, 1)
            
            d = gcd(dy , dx)
            dy /= d
            dx /= d
            
            if dy * dx < 0:
                dy = abs(dy)
                dx = -abs(dx)
            else:
                dy = abs(dy)
                dx = abs(dx)
            
            return  dy, dx
        
        ret =  0
        for i, point1 in enumerate(points):
            if ret > len(points) / 2 or ret >= len(points) - i:
                break 
            counter = dict()
            for j in range(i+1, len(points)):
                point2 = points[j]
                a = grad(point1, point2)
                if a not in counter:
                    counter[a] = 1
                counter[a] += 1
                ret = max(ret, counter[a])
        return ret
# Solution().maxPoints([[1,1],[2,2],[3,3]])
Solution().maxPoints([[0,0],[4,5],[7,8],[8,9],[5,6],[3,4],[1,1]])
Out[35]:
5
In [41]:
class Solution:
    def maxPoints(self, points: List[List[int]]) -> int:
        if len(points) <= 2:
            return len(points)
        max_point = 0
        for i in range(len(points)):
            x,y = points[i][0],points[i][1]
            point_dict = {}
            for j in range(i+1,len(points)):
                if points[j][0] - x  == 0:
                    k = 1e-5
                else:
                    k = (points[j][1] - y) / (points[j][0] - x)
                if k in point_dict:
                    point_dict[k] += 1
                else:
                    point_dict[k] = 2
            print(point_dict)
            if point_dict:
                max_point = max(max_point, max(map(lambda it: it[-1], point_dict.items())))
        return max_point
Solution().maxPoints([[1,1],[2,2],[3,3]])
# Solution().maxPoints([[0,0],[4,5],[7,8],[8,9],[5,6],[3,4],[1,1]])
{1.0: 3}
{1.0: 2}
{}
Out[41]:
3
In [ ]:
(-1.0, -1.0, 1.0): {(3, 4), (4, 5), (8, 9), (5, 6), (7, 8)}, (-4.0, -3.0, -0.33333333333333304): {(1, 1), (4, 5)}, (-7.0, -6.0, -0.16666666666666607): {(1, 1), (7, 8)}, (-8.0, -7.0, -0.14285714285714235): {(1, 1), (8, 9)}, (-5.0, -4.0, -0.25): {(1, 1), (5, 6)}, (-3.0, -2.0, -0.5): {(1, 1), (3, 4)}})

152. 乘积最大子数组¶

In [7]:
class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        ret = nums[0]
        
        dp_max = nums[0]
        dp_min = nums[0]
        for i,it in enumerate(nums):
            if i < 1:
                continue
            dp_max, dp_min =  max((it, dp_max * it, dp_min * it)), min((it, dp_max * it, dp_min * it))
            ret = max(dp_max, ret)
        return ret
Solution().maxProduct([2,3,-2,4,-2])
Out[7]:
96

239.滑动窗口最大值¶

击败 5% 😂¶

image.png

In [ ]:
from collections import deque

class CustDeQueue(deque):
    def __init__(self, *args, **kwargs):
        super(CustDeQueue, self).__init__(*args, **kwargs)
        self._max_val: int = None
        self._dict = dict()
    
    def _calc_max_val(self):
        self._max_val = None
        if self:
            # self._max_val = max(self)
            self._max_val = max(self._dict)
    
    def append(self, x) -> None:
        if self._max_val is None:
            self._max_val = x 
        self._max_val = max(x, self._max_val)
        if x not in self._dict:
            self._dict[x] = 0
        self._dict[x] = self._dict[x] + 1
        return super().append(x)

    def popleft(self):
        pop_val = super().popleft()
        self._dict[pop_val] = self._dict[pop_val] - 1
        if self._dict[pop_val] == 0:
            self._dict.pop(pop_val)
        
        if pop_val == self._max_val and self._dict.get(pop_val) is None:
            self._calc_max_val()
        return pop_val
    
    def get_max(self):
        return self._max_val

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:

        ans: List[int] = []

        window = CustDeQueue()

        n = len(nums)
        for i in range(min(n, k)):
            window.append(nums[i])

        ans.append(window.get_max())
        if n <= k:
            return ans
        
        for num in nums[k:]:
            window.popleft()
            window.append(num)
            ans.append(window.get_max())
        
        return ans

189.轮转数组¶

In [8]:
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        k = k % len(nums)
        temp = nums[-k:]
        nums[k:] = nums[:-k]
        nums[:k] = temp

nums = [1,2,3,4,5,6,7]
nums = [1,2]
Solution().rotate(nums, 3)
nums
Out[8]:
[2, 1]
In [22]:
38 % len([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27])
Out[22]:
11
In [ ]:
class Solution:
    
    def do_rotate(self, nums: List[int], k: int, start: int, end: int):
        def swap(s1, e1, s2, e2):
            e1 = min(e1, s2)
            er1 = e1 - s1
            er2 = e2 - s2
            _range = min(er1, er2)
            for i in range(_range):
                nums[s1+i], nums[s2+i] = nums[s2+i], nums[s1+i]
            if er1 != er2:
                self.do_rotate(nums, er2 -er1, s2, e2)
 
        for i in range(start, end, k):
            if i >= end - k:
                break
            swap(i, i + k, end-k, end)    
    
    def rotate(self, nums: List[int], k: int) -> None:
        k = k % len(nums)
        if k == 0:
            return
        n = len(nums)
        self.do_rotate(nums, k, 0, n)
        
        

# nums = [1,2,3,4,5,6,7]
# Solution().rotate(nums, 3)
nums = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27]
Solution().rotate(nums, 38)
nums

方法一中使用额外数组的原因在于如果我们直接将每个数字放至它最后的位置,这样被放置位置的元素会被覆盖从而丢失。因此,从另一个角度,我们可以将被替换的元素保存在变量 temp 中,从而避免了额外数组的开销。

我们从位置 0 开始,最初令 temp=nums[0]。根据规则,位置 0 的元素会放至 (0+k)modn 的位置,令 x=(0+k)modn,此时交换 temp 和 nums[x],完成位置 x 的更新。然后,我们考察位置 x,并交换 temp 和 nums[(x+k)modn],从而完成下一个位置的更新。不断进行上述过程,直至回到初始位置 0。

容易发现,当回到初始位置 0 时,有些数字可能还没有遍历到,此时我们应该从下一个数字开始重复的过程,可是这个时候怎么才算遍历结束呢?我们不妨先考虑这样一个问题:从 0 开始不断遍历,最终回到起点 0 的过程中,我们遍历了多少个元素?

由于最终回到了起点,故该过程恰好走了整数数量的圈,不妨设为 a 圈;再设该过程总共遍历了 b 个元素。因此,我们有 an=bk,即 an 一定为 n,k 的公倍数。又因为我们在第一次回到起点时就结束,因此 a 要尽可能小,故 an 就是 n,k 的最小公倍数 lcm(n,k),因此 b 就为 lcm(n,k)/k。

这说明单次遍历会访问到 lcm(n,k)/k 个元素。为了访问到所有的元素,我们需要进行遍历的次数为 lcm(n,k)/kn​=lcm(n,k)nk​=gcd(n,k)

其中 gcd 指的是最大公约数。

我们用下面的例子更具体地说明这个过程:

class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k = k % n;
        int count = gcd(k, n);
        for (int start = 0; start < count; ++start) {
            int current = start;
            int prev = nums[start];
            do {
                int next = (current + k) % n;
                int temp = nums[next];
                nums[next] = prev;
                prev = temp;
                current = next;
            } while (start != current);
        }
    }

    public int gcd(int x, int y) {
        return y > 0 ? gcd(y, x % y) : x;
    }
}